Commit b1eeba1f by Jamie Madill Committed by Commit Bot

Use a C API for the ANGLE platform.

The main purpose of this change is to fix a fuzzer bug where we would trigger undefined behaviour calling between Chrome and ANGLE. It's not specced how virtual function calls work if the shared objects are not directly linked together, and ANGLE and Chrome are not linked. Replace the old class-style API with a C dispatch table. Follow-up work will make the Platform owned by the Display instead of using global variables, but fixing this is a bit tricky. BUG=angleproject:1892 BUG=chromium:678870 Change-Id: Iad188bc2e50f2b5e4a03ce0de233d686f569c705 Reviewed-on: https://chromium-review.googlesource.com/441273 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent c47e3407
......@@ -34,6 +34,8 @@ namespace angle
{
struct WorkaroundsD3D;
using TraceEventHandle = uint64_t;
using EGLDisplayType = void *;
class Platform
{
......@@ -154,7 +156,7 @@ class Platform
virtual ~Platform() { }
};
}
} // namespace angle
extern "C"
{
......@@ -164,10 +166,235 @@ ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platfor
typedef void (ANGLE_APIENTRY *ANGLEPlatformShutdownFunc)();
ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformShutdown();
}
namespace angle
{
struct PlatformMethods;
// Use a C-like API to not trigger undefined calling behaviour.
// System --------------------------------------------------------------
// Wall clock time in seconds since the epoch.
// TODO(jmadill): investigate using an ANGLE internal time library
inline double ANGLE_currentTime(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.
inline double ANGLE_monotonicallyIncreasingTime(PlatformMethods *platform)
{
return 0.0;
}
// Logging ------------------------------------------------------------
// Log an error message within the platform implementation.
inline void ANGLE_logError(PlatformMethods *platform, const char *errorMessage)
{
}
// Log a warning message within the platform implementation.
inline void ANGLE_logWarning(PlatformMethods *platform, const char *warningMessage)
{
}
// Log an info message within the platform implementation.
inline void ANGLE_logInfo(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.
inline const unsigned char *ANGLE_getTraceCategoryEnabledFlag(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 consutruction 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.
inline angle::TraceEventHandle ANGLE_addTraceEvent(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.
inline void ANGLE_updateTraceEventDuration(PlatformMethods *platform,
const unsigned char *categoryEnabledFlag,
const char *name,
angle::TraceEventHandle eventHandle)
{
}
typedef angle::Platform *(ANGLE_APIENTRY *ANGLEPlatformCurrentFunc)();
ANGLE_PLATFORM_EXPORT angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent();
// Callbacks for reporting histogram data.
// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50
// would do.
inline void ANGLE_histogramCustomCounts(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.
inline void ANGLE_histogramEnumeration(PlatformMethods *platform,
const char *name,
int sample,
int boundaryValue)
{
}
// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets.
inline void ANGLE_histogramSparse(PlatformMethods *platform, const char *name, int sample)
{
}
// Boolean histograms track two-state variables.
inline void ANGLE_histogramBoolean(PlatformMethods *platform, const char *name, bool sample)
{
}
// Allows us to programatically override ANGLE's default workarounds for testing purposes.
inline void ANGLE_overrideWorkaroundsD3D(PlatformMethods *platform,
angle::WorkaroundsD3D *workaroundsD3D)
{
}
// Platform methods are enumerated here once.
#define ANGLE_PLATFORM_OP(OP) \
OP(currentTime) \
OP(monotonicallyIncreasingTime) \
OP(logError) \
OP(logWarning) \
OP(logInfo) \
OP(getTraceCategoryEnabledFlag) \
OP(addTraceEvent) \
OP(updateTraceEventDuration) \
OP(histogramCustomCounts) \
OP(histogramEnumeration) \
OP(histogramSparse) \
OP(histogramBoolean) \
OP(overrideWorkaroundsD3D)
#define ANGLE_PLATFORM_METHOD_DEF(Name) decltype(&ANGLE_##Name) Name = ANGLE_##Name;
struct PlatformMethods
{
ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF);
// User data pointer for any implementation specific members.
uintptr_t context = 0;
};
#undef ANGLE_PLATFORM_METHOD_DEF
constexpr unsigned int g_NumPlatformMethods = sizeof(PlatformMethods) / sizeof(uintptr_t);
#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name
#define ANGLE_PLATFORM_METHOD_STRING2(Name) 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,
uintptr_t context,
angle::PlatformMethods **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
{
using GetDisplayPlatformFunc = decltype(&ANGLEGetDisplayPlatform);
using ResetDisplayPlatformFunc = decltype(&ANGLEResetDisplayPlatform);
} // namespace angle
// This function is not exported
angle::PlatformMethods *ANGLEPlatformCurrent();
#endif // ANGLE_PLATFORM_H
......@@ -11,10 +11,11 @@ namespace angle
const unsigned char *GetTraceCategoryEnabledFlag(const char *name)
{
angle::Platform *platform = ANGLEPlatformCurrent();
auto *platform = ANGLEPlatformCurrent();
ASSERT(platform);
const unsigned char *categoryEnabledFlag = platform->getTraceCategoryEnabledFlag(name);
const unsigned char *categoryEnabledFlag =
platform->getTraceCategoryEnabledFlag(platform, name);
if (categoryEnabledFlag != nullptr)
{
return categoryEnabledFlag;
......@@ -24,28 +25,26 @@ const unsigned char *GetTraceCategoryEnabledFlag(const char *name)
return &disabled;
}
Platform::TraceEventHandle AddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id,
int numArgs, const char** argNames, const unsigned char* argTypes,
const unsigned long long* argValues, unsigned char flags)
angle::TraceEventHandle AddTraceEvent(char phase,
const unsigned char *categoryGroupEnabled,
const char *name,
unsigned long long id,
int numArgs,
const char **argNames,
const unsigned char *argTypes,
const unsigned long long *argValues,
unsigned char flags)
{
angle::Platform *platform = ANGLEPlatformCurrent();
auto *platform = ANGLEPlatformCurrent();
ASSERT(platform);
double timestamp = platform->monotonicallyIncreasingTime();
double timestamp = platform->monotonicallyIncreasingTime(platform);
if (timestamp != 0)
{
angle::Platform::TraceEventHandle handle =
platform->addTraceEvent(phase,
categoryGroupEnabled,
name,
id,
timestamp,
numArgs,
argNames,
argTypes,
argValues,
flags);
angle::TraceEventHandle handle =
platform->addTraceEvent(platform, phase, categoryGroupEnabled, name, id, timestamp,
numArgs, argNames, argTypes, argValues, flags);
ASSERT(handle != 0);
return handle;
}
......
......@@ -12,11 +12,15 @@ namespace angle
{
const unsigned char *GetTraceCategoryEnabledFlag(const char* name);
Platform::TraceEventHandle AddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name,
unsigned long long id, int numArgs, const char** argNames,
const unsigned char* argTypes, const unsigned long long* argValues,
unsigned char flags);
angle::TraceEventHandle AddTraceEvent(char phase,
const unsigned char *categoryGroupEnabled,
const char *name,
unsigned long long id,
int numArgs,
const char **argNames,
const unsigned char *argTypes,
const unsigned long long *argValues,
unsigned char flags);
}
#endif // COMMON_EVENT_TRACER_H_
......@@ -15,16 +15,16 @@ namespace angle
void LoggingAnnotator::logMessage(const gl::LogMessage &msg) const
{
angle::Platform *plat = ANGLEPlatformCurrent();
auto *plat = ANGLEPlatformCurrent();
if (plat != nullptr)
{
switch (msg.getSeverity())
{
case gl::LOG_ERR:
plat->logError(msg.getMessage().c_str());
plat->logError(plat, msg.getMessage().c_str());
break;
case gl::LOG_WARN:
plat->logWarning(msg.getMessage().c_str());
plat->logWarning(plat, msg.getMessage().c_str());
break;
default:
UNREACHABLE();
......
......@@ -8,28 +8,176 @@
#include <platform/Platform.h>
#include <cstring>
#include "common/debug.h"
namespace
{
angle::Platform *currentPlatform = nullptr;
// TODO(jmadill): Make methods owned by egl::Display.
angle::PlatformMethods g_platformMethods;
// TODO(jmadill): Remove all the Class_ methods once we switch Chromium to the new impl.
double Class_currentTime(angle::PlatformMethods *platform)
{
return currentPlatform->currentTime();
}
double Class_monotonicallyIncreasingTime(angle::PlatformMethods *platform)
{
return currentPlatform->monotonicallyIncreasingTime();
}
void Class_logError(angle::PlatformMethods *platform, const char *errorMessage)
{
currentPlatform->logError(errorMessage);
}
void Class_logWarning(angle::PlatformMethods *platform, const char *warningMessage)
{
currentPlatform->logWarning(warningMessage);
}
void Class_logInfo(angle::PlatformMethods *platform, const char *infoMessage)
{
currentPlatform->logInfo(infoMessage);
}
const unsigned char *Class_getTraceCategoryEnabledFlag(angle::PlatformMethods *platform,
const char *categoryName)
{
return currentPlatform->getTraceCategoryEnabledFlag(categoryName);
}
angle::TraceEventHandle Class_addTraceEvent(angle::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 currentPlatform->addTraceEvent(phase, categoryEnabledFlag, name, id, timestamp, numArgs,
argNames, argTypes, argValues, flags);
}
void Class_updateTraceEventDuration(angle::PlatformMethods *platform,
const unsigned char *categoryEnabledFlag,
const char *name,
angle::TraceEventHandle eventHandle)
{
currentPlatform->updateTraceEventDuration(categoryEnabledFlag, name, eventHandle);
}
// static
angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent()
void Class_histogramCustomCounts(angle::PlatformMethods *platform,
const char *name,
int sample,
int min,
int max,
int bucketCount)
{
return currentPlatform;
currentPlatform->histogramCustomCounts(name, sample, min, max, bucketCount);
}
void Class_histogramEnumeration(angle::PlatformMethods *platform,
const char *name,
int sample,
int boundaryValue)
{
currentPlatform->histogramEnumeration(name, sample, boundaryValue);
}
void Class_histogramSparse(angle::PlatformMethods *platform, const char *name, int sample)
{
currentPlatform->histogramSparse(name, sample);
}
void Class_histogramBoolean(angle::PlatformMethods *platform, const char *name, bool sample)
{
currentPlatform->histogramBoolean(name, sample);
}
void Class_overrideWorkaroundsD3D(angle::PlatformMethods *platform,
angle::WorkaroundsD3D *workaroundsD3D)
{
currentPlatform->overrideWorkaroundsD3D(workaroundsD3D);
}
} // anonymous namespace
angle::PlatformMethods *ANGLEPlatformCurrent()
{
return &g_platformMethods;
}
// static
void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platform *platformImpl)
{
ASSERT(platformImpl != nullptr);
currentPlatform = platformImpl;
// TODO(jmadill): Migrate to platform methods.
g_platformMethods.addTraceEvent = Class_addTraceEvent;
g_platformMethods.currentTime = Class_currentTime;
g_platformMethods.getTraceCategoryEnabledFlag = Class_getTraceCategoryEnabledFlag;
g_platformMethods.histogramBoolean = Class_histogramBoolean;
g_platformMethods.histogramCustomCounts = Class_histogramCustomCounts;
g_platformMethods.histogramEnumeration = Class_histogramEnumeration;
g_platformMethods.histogramSparse = Class_histogramSparse;
g_platformMethods.logError = Class_logError;
g_platformMethods.logInfo = Class_logInfo;
g_platformMethods.logWarning = Class_logWarning;
g_platformMethods.monotonicallyIncreasingTime = Class_monotonicallyIncreasingTime;
g_platformMethods.overrideWorkaroundsD3D = Class_overrideWorkaroundsD3D;
g_platformMethods.updateTraceEventDuration = Class_updateTraceEventDuration;
}
// static
void ANGLE_APIENTRY ANGLEPlatformShutdown()
{
currentPlatform = nullptr;
g_platformMethods = angle::PlatformMethods();
}
bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
const char *const methodNames[],
unsigned int methodNameCount,
uintptr_t context,
angle::PlatformMethods **platformMethodsOut)
{
// We allow for a lower input count of impl platform methods if the subset is correct.
if (methodNameCount > angle::g_NumPlatformMethods)
{
ERR() << "Invalid platform method count: " << methodNameCount << ", expected "
<< angle::g_NumPlatformMethods << ".";
return false;
}
for (unsigned int nameIndex = 0; nameIndex < methodNameCount; ++nameIndex)
{
const char *expectedName = angle::g_PlatformMethodNames[nameIndex];
const char *actualName = methodNames[nameIndex];
if (strcmp(expectedName, actualName) != 0)
{
ERR() << "Invalid platform method name: " << actualName << ", expected " << expectedName
<< ".";
return false;
}
}
// TODO(jmadill): Store platform methods in display.
g_platformMethods.context = context;
*platformMethodsOut = &g_platformMethods;
return true;
}
void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display)
{
// TODO(jmadill): Store platform methods in display.
g_platformMethods = angle::PlatformMethods();
g_platformMethods.context = 0;
}
......@@ -41,18 +41,19 @@
#define ANGLE_HISTOGRAM_COUNTS_10000(name, sample) \
ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50)
#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
ANGLEPlatformCurrent()->histogramCustomCounts(\
name, sample, min, max, bucket_count)
#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
ANGLEPlatformCurrent()->histogramCustomCounts(ANGLEPlatformCurrent(), name, sample, min, max, \
bucket_count)
#define ANGLE_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
ANGLE_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
#define ANGLE_HISTOGRAM_BOOLEAN(name, sample) \
ANGLEPlatformCurrent()->histogramBoolean(name, sample)
ANGLEPlatformCurrent()->histogramBoolean(ANGLEPlatformCurrent(), name, sample)
#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
ANGLEPlatformCurrent()->histogramEnumeration(name, sample, boundary_value)
#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
ANGLEPlatformCurrent()->histogramEnumeration(ANGLEPlatformCurrent(), name, sample, \
boundary_value)
#define ANGLE_HISTOGRAM_MEMORY_KB(name, sample) ANGLE_HISTOGRAM_CUSTOM_COUNTS( \
name, sample, 1000, 500000, 50)
......@@ -61,7 +62,7 @@
name, sample, 1, 1000, 50)
#define ANGLE_HISTOGRAM_SPARSE_SLOWLY(name, sample) \
ANGLEPlatformCurrent()->histogramSparse(name, sample)
ANGLEPlatformCurrent()->histogramSparse(ANGLEPlatformCurrent(), name, sample)
// Scoped class which logs its time on this earth as a UMA statistic. This is
// recommended for when you want a histogram which measures the time it takes
......@@ -79,29 +80,33 @@
#define SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \
SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key)
#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \
class ScopedHistogramTimer##key \
{ \
public: \
ScopedHistogramTimer##key() : constructed_(ANGLEPlatformCurrent()->currentTime()) {} \
~ScopedHistogramTimer##key() \
{ \
if (constructed_ == 0) \
return; \
double elapsed = ANGLEPlatformCurrent()->currentTime() - constructed_; \
int elapsedMS = static_cast<int>(elapsed * 1000.0); \
if (is_long) \
{ \
ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \
} \
else \
{ \
ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \
} \
} \
\
private: \
double constructed_; \
#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \
class ScopedHistogramTimer##key \
{ \
public: \
ScopedHistogramTimer##key() \
: constructed_(ANGLEPlatformCurrent()->currentTime(ANGLEPlatformCurrent())) \
{ \
} \
~ScopedHistogramTimer##key() \
{ \
if (constructed_ == 0) \
return; \
auto *platform = ANGLEPlatformCurrent(); \
double elapsed = platform->currentTime(platform) - constructed_; \
int elapsedMS = static_cast<int>(elapsed * 1000.0); \
if (is_long) \
{ \
ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \
} \
else \
{ \
ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \
} \
} \
\
private: \
double constructed_; \
} scoped_histogram_timer_##key
#endif // BASE_METRICS_HISTOGRAM_MACROS_H_
......@@ -387,7 +387,8 @@ Renderer11::Renderer11(egl::Display *display)
: RendererD3D(display),
mStateCache(this),
mStateManager(this),
mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()),
mLastHistogramUpdateTime(
ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())),
mDebug(nullptr),
mScratchMemoryBufferResetCounter(0),
mAnnotator(nullptr)
......@@ -4294,7 +4295,8 @@ void Renderer11::onSwap()
// Send histogram updates every half hour
const double kHistogramUpdateInterval = 30 * 60;
const double currentTime = ANGLEPlatformCurrent()->monotonicallyIncreasingTime();
auto *platform = ANGLEPlatformCurrent();
const double currentTime = platform->monotonicallyIncreasingTime(platform);
const double timeSinceLastUpdate = currentTime - mLastHistogramUpdateTime;
if (timeSinceLastUpdate > kHistogramUpdateInterval)
......
......@@ -1988,7 +1988,8 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
}
// Call platform hooks for testing overrides.
ANGLEPlatformCurrent()->overrideWorkaroundsD3D(&workarounds);
auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, &workarounds);
return workarounds;
}
......
......@@ -654,7 +654,8 @@ angle::WorkaroundsD3D GenerateWorkarounds()
workarounds.expandIntegerPowExpressions = true;
// Call platform hooks for testing overrides.
ANGLEPlatformCurrent()->overrideWorkaroundsD3D(&workarounds);
auto *platform = ANGLEPlatformCurrent();
platform->overrideWorkaroundsD3D(platform, &workarounds);
return workarounds;
}
......
......@@ -1773,6 +1773,8 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *
// angle::Platform related entry points
INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformInitialize", ANGLEPlatformInitialize);
INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformShutdown", ANGLEPlatformShutdown);
INSERT_PROC_ADDRESS_NO_NS("ANGLEGetDisplayPlatform", ANGLEGetDisplayPlatform);
INSERT_PROC_ADDRESS_NO_NS("ANGLEResetDisplayPlatform", ANGLEResetDisplayPlatform);
#undef INSERT_PROC_ADDRESS
#undef INSERT_PROC_ADDRESS_NO_NS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment