339 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			339 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
//
 | 
						|
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style license that can be
 | 
						|
// found in the LICENSE file.
 | 
						|
 | 
						|
// Platform.h: The public interface ANGLE exposes to the API layer, for
 | 
						|
//   doing platform-specific tasks like gathering data, or for tracing.
 | 
						|
 | 
						|
#ifndef ANGLE_PLATFORM_H
 | 
						|
#define ANGLE_PLATFORM_H
 | 
						|
 | 
						|
#include <stdint.h>
 | 
						|
#include <array>
 | 
						|
 | 
						|
#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x3482
 | 
						|
 | 
						|
#if defined(_WIN32)
 | 
						|
#   if !defined(LIBANGLE_IMPLEMENTATION)
 | 
						|
#       define ANGLE_PLATFORM_EXPORT __declspec(dllimport)
 | 
						|
#   else
 | 
						|
#       define ANGLE_PLATFORM_EXPORT __declspec(dllexport)
 | 
						|
#   endif
 | 
						|
#elif defined(__GNUC__) || defined(__clang__)
 | 
						|
#   define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default")))
 | 
						|
#endif
 | 
						|
#if !defined(ANGLE_PLATFORM_EXPORT)
 | 
						|
#   define ANGLE_PLATFORM_EXPORT
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(_WIN32)
 | 
						|
#   define ANGLE_APIENTRY __stdcall
 | 
						|
#else
 | 
						|
#   define ANGLE_APIENTRY
 | 
						|
#endif
 | 
						|
 | 
						|
namespace angle
 | 
						|
{
 | 
						|
struct WorkaroundsD3D;
 | 
						|
struct FeaturesVk;
 | 
						|
using TraceEventHandle = uint64_t;
 | 
						|
using EGLDisplayType   = void *;
 | 
						|
struct PlatformMethods;
 | 
						|
 | 
						|
// Use a C-like API to not trigger undefined calling behaviour.
 | 
						|
// Avoid using decltype here to work around sanitizer limitations.
 | 
						|
// TODO(jmadill): Use decltype here if/when UBSAN is fixed.
 | 
						|
 | 
						|
// System --------------------------------------------------------------
 | 
						|
 | 
						|
// Wall clock time in seconds since the epoch.
 | 
						|
// TODO(jmadill): investigate using an ANGLE internal time library
 | 
						|
using CurrentTimeFunc = double (*)(PlatformMethods *platform);
 | 
						|
inline double DefaultCurrentTime(PlatformMethods *platform)
 | 
						|
{
 | 
						|
    return 0.0;
 | 
						|
}
 | 
						|
 | 
						|
// Monotonically increasing time in seconds from an arbitrary fixed point in the past.
 | 
						|
// This function is expected to return at least millisecond-precision values. For this reason,
 | 
						|
// it is recommended that the fixed point be no further in the past than the epoch.
 | 
						|
using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform);
 | 
						|
inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform)
 | 
						|
{
 | 
						|
    return 0.0;
 | 
						|
}
 | 
						|
 | 
						|
// Logging ------------------------------------------------------------
 | 
						|
 | 
						|
// Log an error message within the platform implementation.
 | 
						|
using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage);
 | 
						|
inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Log a warning message within the platform implementation.
 | 
						|
using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage);
 | 
						|
inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Log an info message within the platform implementation.
 | 
						|
using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage);
 | 
						|
inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Tracing --------
 | 
						|
 | 
						|
// Get a pointer to the enabled state of the given trace category. The
 | 
						|
// embedder can dynamically change the enabled state as trace event
 | 
						|
// recording is started and stopped by the application. Only long-lived
 | 
						|
// literal strings should be given as the category name. The implementation
 | 
						|
// expects the returned pointer to be held permanently in a local static. If
 | 
						|
// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
 | 
						|
// addTraceEvent is expected to be called by the trace event macros.
 | 
						|
using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform,
 | 
						|
                                                                 const char *categoryName);
 | 
						|
inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform,
 | 
						|
                                                               const char *categoryName)
 | 
						|
{
 | 
						|
    return nullptr;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Add a trace event to the platform tracing system. Depending on the actual
 | 
						|
// enabled state, this event may be recorded or dropped.
 | 
						|
// - phase specifies the type of event:
 | 
						|
//   - BEGIN ('B'): Marks the beginning of a scoped event.
 | 
						|
//   - END ('E'): Marks the end of a scoped event.
 | 
						|
//   - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't
 | 
						|
//     need a matching END event. Instead, at the end of the scope,
 | 
						|
//     updateTraceEventDuration() must be called with the TraceEventHandle
 | 
						|
//     returned from addTraceEvent().
 | 
						|
//   - INSTANT ('I'): Standalone, instantaneous event.
 | 
						|
//   - START ('S'): Marks the beginning of an asynchronous event (the end
 | 
						|
//     event can occur in a different scope or thread). The id parameter is
 | 
						|
//     used to match START/FINISH pairs.
 | 
						|
//   - FINISH ('F'): Marks the end of an asynchronous event.
 | 
						|
//   - COUNTER ('C'): Used to trace integer quantities that change over
 | 
						|
//     time. The argument values are expected to be of type int.
 | 
						|
//   - METADATA ('M'): Reserved for internal use.
 | 
						|
// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag.
 | 
						|
// - name is the name of the event. Also used to match BEGIN/END and
 | 
						|
//   START/FINISH pairs.
 | 
						|
// - id optionally allows events of the same name to be distinguished from
 | 
						|
//   each other. For example, to trace the construction and destruction of
 | 
						|
//   objects, specify the pointer as the id parameter.
 | 
						|
// - timestamp should be a time value returned from monotonicallyIncreasingTime.
 | 
						|
// - numArgs specifies the number of elements in argNames, argTypes, and
 | 
						|
//   argValues.
 | 
						|
// - argNames is the array of argument names. Use long-lived literal strings
 | 
						|
//   or specify the COPY flag.
 | 
						|
// - argTypes is the array of argument types:
 | 
						|
//   - BOOL (1): bool
 | 
						|
//   - UINT (2): unsigned long long
 | 
						|
//   - INT (3): long long
 | 
						|
//   - DOUBLE (4): double
 | 
						|
//   - POINTER (5): void*
 | 
						|
//   - STRING (6): char* (long-lived null-terminated char* string)
 | 
						|
//   - COPY_STRING (7): char* (temporary null-terminated char* string)
 | 
						|
//   - CONVERTABLE (8): WebConvertableToTraceFormat
 | 
						|
// - argValues is the array of argument values. Each value is the unsigned
 | 
						|
//   long long member of a union of all supported types.
 | 
						|
// - flags can be 0 or one or more of the following, ORed together:
 | 
						|
//   - COPY (0x1): treat all strings (name, argNames and argValues of type
 | 
						|
//     string) as temporary so that they will be copied by addTraceEvent.
 | 
						|
//   - HAS_ID (0x2): use the id argument to uniquely identify the event for
 | 
						|
//     matching with other events of the same name.
 | 
						|
//   - MANGLE_ID (0x4): specify this flag if the id parameter is the value
 | 
						|
//     of a pointer.
 | 
						|
using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform,
 | 
						|
                                                      char phase,
 | 
						|
                                                      const unsigned char *categoryEnabledFlag,
 | 
						|
                                                      const char *name,
 | 
						|
                                                      unsigned long long id,
 | 
						|
                                                      double timestamp,
 | 
						|
                                                      int numArgs,
 | 
						|
                                                      const char **argNames,
 | 
						|
                                                      const unsigned char *argTypes,
 | 
						|
                                                      const unsigned long long *argValues,
 | 
						|
                                                      unsigned char flags);
 | 
						|
inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform,
 | 
						|
                                                    char phase,
 | 
						|
                                                    const unsigned char *categoryEnabledFlag,
 | 
						|
                                                    const char *name,
 | 
						|
                                                    unsigned long long id,
 | 
						|
                                                    double timestamp,
 | 
						|
                                                    int numArgs,
 | 
						|
                                                    const char **argNames,
 | 
						|
                                                    const unsigned char *argTypes,
 | 
						|
                                                    const unsigned long long *argValues,
 | 
						|
                                                    unsigned char flags)
 | 
						|
{
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
// Set the duration field of a COMPLETE trace event.
 | 
						|
using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                              const unsigned char *categoryEnabledFlag,
 | 
						|
                                              const char *name,
 | 
						|
                                              angle::TraceEventHandle eventHandle);
 | 
						|
inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform,
 | 
						|
                                            const unsigned char *categoryEnabledFlag,
 | 
						|
                                            const char *name,
 | 
						|
                                            angle::TraceEventHandle eventHandle)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Callbacks for reporting histogram data.
 | 
						|
// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
 | 
						|
// would do.
 | 
						|
using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                           const char *name,
 | 
						|
                                           int sample,
 | 
						|
                                           int min,
 | 
						|
                                           int max,
 | 
						|
                                           int bucketCount);
 | 
						|
inline void DefaultHistogramCustomCounts(PlatformMethods *platform,
 | 
						|
                                         const char *name,
 | 
						|
                                         int sample,
 | 
						|
                                         int min,
 | 
						|
                                         int max,
 | 
						|
                                         int bucketCount)
 | 
						|
{
 | 
						|
}
 | 
						|
// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample
 | 
						|
// value.
 | 
						|
using HistogramEnumerationFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                          const char *name,
 | 
						|
                                          int sample,
 | 
						|
                                          int boundaryValue);
 | 
						|
inline void DefaultHistogramEnumeration(PlatformMethods *platform,
 | 
						|
                                        const char *name,
 | 
						|
                                        int sample,
 | 
						|
                                        int boundaryValue)
 | 
						|
{
 | 
						|
}
 | 
						|
// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
 | 
						|
using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample);
 | 
						|
inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample)
 | 
						|
{
 | 
						|
}
 | 
						|
// Boolean histograms track two-state variables.
 | 
						|
using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample);
 | 
						|
inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Allows us to programatically override ANGLE's default workarounds for testing purposes.
 | 
						|
using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                            angle::WorkaroundsD3D *workaroundsD3D);
 | 
						|
inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform,
 | 
						|
                                          angle::WorkaroundsD3D *workaroundsD3D)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
using OverrideFeaturesVkFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                        angle::FeaturesVk *workaroundsVulkan);
 | 
						|
inline void DefaultOverrideFeaturesVk(PlatformMethods *platform,
 | 
						|
                                      angle::FeaturesVk *workaroundsVulkan)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Callback on a successful program link with the program binary. Can be used to store
 | 
						|
// shaders to disk. Keys are a 160-bit SHA-1 hash.
 | 
						|
using ProgramKeyType   = std::array<uint8_t, 20>;
 | 
						|
using CacheProgramFunc = void (*)(PlatformMethods *platform,
 | 
						|
                                  const ProgramKeyType &key,
 | 
						|
                                  size_t programSize,
 | 
						|
                                  const uint8_t *programBytes);
 | 
						|
inline void DefaultCacheProgram(PlatformMethods *platform,
 | 
						|
                                const ProgramKeyType &key,
 | 
						|
                                size_t programSize,
 | 
						|
                                const uint8_t *programBytes)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
// Platform methods are enumerated here once.
 | 
						|
#define ANGLE_PLATFORM_OP(OP)                                    \
 | 
						|
    OP(currentTime, CurrentTime)                                 \
 | 
						|
    OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \
 | 
						|
    OP(logError, LogError)                                       \
 | 
						|
    OP(logWarning, LogWarning)                                   \
 | 
						|
    OP(logInfo, LogInfo)                                         \
 | 
						|
    OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \
 | 
						|
    OP(addTraceEvent, AddTraceEvent)                             \
 | 
						|
    OP(updateTraceEventDuration, UpdateTraceEventDuration)       \
 | 
						|
    OP(histogramCustomCounts, HistogramCustomCounts)             \
 | 
						|
    OP(histogramEnumeration, HistogramEnumeration)               \
 | 
						|
    OP(histogramSparse, HistogramSparse)                         \
 | 
						|
    OP(histogramBoolean, HistogramBoolean)                       \
 | 
						|
    OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D)           \
 | 
						|
    OP(overrideFeaturesVk, OverrideFeaturesVk)                   \
 | 
						|
    OP(cacheProgram, CacheProgram)
 | 
						|
 | 
						|
#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName;
 | 
						|
 | 
						|
struct ANGLE_PLATFORM_EXPORT PlatformMethods
 | 
						|
{
 | 
						|
    PlatformMethods() {}
 | 
						|
 | 
						|
    // User data pointer for any implementation specific members. Put it at the start of the
 | 
						|
    // platform structure so it doesn't become overwritten if one version of the platform
 | 
						|
    // adds or removes new members.
 | 
						|
    void *context = 0;
 | 
						|
 | 
						|
    ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
 | 
						|
};
 | 
						|
 | 
						|
#undef ANGLE_PLATFORM_METHOD_DEF
 | 
						|
 | 
						|
// Subtract one to account for the context pointer.
 | 
						|
constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1;
 | 
						|
 | 
						|
#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
 | 
						|
#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name),
 | 
						|
 | 
						|
constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = {
 | 
						|
    ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)};
 | 
						|
 | 
						|
#undef ANGLE_PLATFORM_METHOD_STRING2
 | 
						|
#undef ANGLE_PLATFORM_METHOD_STRING
 | 
						|
 | 
						|
}  // namespace angle
 | 
						|
 | 
						|
extern "C" {
 | 
						|
 | 
						|
// Gets the platform methods on the passed-in EGL display. If the method name signature does not
 | 
						|
// match the compiled signature for this ANGLE, false is returned. On success true is returned.
 | 
						|
// The application should set any platform methods it cares about on the returned pointer.
 | 
						|
// If display is not valid, behaviour is undefined.
 | 
						|
 | 
						|
ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
 | 
						|
                                                                  const char *const methodNames[],
 | 
						|
                                                                  unsigned int methodNameCount,
 | 
						|
                                                                  void *context,
 | 
						|
                                                                  void *platformMethodsOut);
 | 
						|
 | 
						|
// Sets the platform methods back to their defaults.
 | 
						|
// If display is not valid, behaviour is undefined.
 | 
						|
ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display);
 | 
						|
 | 
						|
}  // extern "C"
 | 
						|
 | 
						|
namespace angle
 | 
						|
{
 | 
						|
typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType,
 | 
						|
                                                     const char *const *,
 | 
						|
                                                     unsigned int,
 | 
						|
                                                     void *,
 | 
						|
                                                     void *);
 | 
						|
typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType);
 | 
						|
}  // namespace angle
 | 
						|
 | 
						|
// This function is not exported
 | 
						|
angle::PlatformMethods *ANGLEPlatformCurrent();
 | 
						|
 | 
						|
#endif // ANGLE_PLATFORM_H
 |