17#include "third_party/externals/angle2/include/platform/PlatformMethods.h"
21#define EGL_EGL_PROTOTYPES 1
23#include <EGL/eglext.h>
25#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
26#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
27#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
28#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
29#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
30#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
32#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483
44 auto display = eglGetCurrentDisplay();
45 auto dsurface = eglGetCurrentSurface(EGL_DRAW);
46 auto rsurface = eglGetCurrentSurface(EGL_READ);
47 auto context = eglGetCurrentContext();
48 return [display, dsurface, rsurface, context] {
49 eglMakeCurrent(display, dsurface, rsurface, context);
54 const Libs*
libs =
reinterpret_cast<const Libs*
>(ctx);
63 return eglGetProcAddress(
name);
67 PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
68 eglGetPlatformDisplayEXT =
69 (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress(
"eglGetPlatformDisplayEXT");
72 if (!eglGetPlatformDisplayEXT) {
73 return EGL_NO_DISPLAY;
78 case ANGLEBackend::kD3D9:
81 case ANGLEBackend::kD3D11:
98 ~ANGLEGLContext()
override;
101 void destroyEGLImage(
GrEGLImage)
const override;
103 std::unique_ptr<sk_gpu_test::GLTestContext> makeNew()
const override;
106 void destroyGLContext();
108 void onPlatformMakeNotCurrent()
const override;
109 void onPlatformMakeCurrent()
const override;
110 std::function<void()> onPlatformGetAutoContextRestore()
const override;
120 angle::ResetDisplayPlatformFunc fResetPlatform =
nullptr;
122 PFNEGLCREATEIMAGEKHRPROC fCreateImage =
nullptr;
123 PFNEGLDESTROYIMAGEKHRPROC fDestroyImage =
nullptr;
125#ifdef SK_BUILD_FOR_WIN
132#ifdef SK_BUILD_FOR_WIN
133ATOM ANGLEGLContext::gWC = 0;
137static IsWine is_wine() {
138 HMODULE ntdll = GetModuleHandle(
"ntdll.dll");
140 SkDebugf(
"No ntdll.dll on Windows?!\n");
143 return GetProcAddress(ntdll,
"wine_get_version") ==
nullptr ? IsWine::kNo : IsWine::kYes;
148static const unsigned char* ANGLE_getTraceCategoryEnabledFlag(angle::PlatformMethods* platform,
149 const char* category_group) {
153static angle::TraceEventHandle ANGLE_addTraceEvent(angle::PlatformMethods* platform,
155 const unsigned char* category_group_enabled,
157 unsigned long long id,
160 const char** arg_names,
161 const unsigned char* arg_types,
162 const unsigned long long* arg_values,
163 unsigned char flags) {
164 static_assert(
sizeof(
unsigned long long) ==
sizeof(uint64_t),
"Non-64-bit trace event args!");
166 phase, category_group_enabled,
name,
id, num_args, arg_names, arg_types,
167 reinterpret_cast<const uint64_t*
>(arg_values),
flags);
170static void ANGLE_updateTraceEventDuration(angle::PlatformMethods* platform,
171 const unsigned char* category_group_enabled,
173 angle::TraceEventHandle handle) {
177static double ANGLE_monotonicallyIncreasingTime(angle::PlatformMethods* platform) {
182 ANGLEGLContext* shareContext,
void* display)
185 , fSurface(EGL_NO_SURFACE)
188 , fOwnsDisplay(
false) {
189#ifdef SK_BUILD_FOR_WIN
191 fDeviceContext =
nullptr;
193 static IsWine gIsWine = is_wine();
201 if (EGL_NO_DISPLAY == fDisplay) {
202 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(
nullptr);
208 wc.hbrBackground =
nullptr;
209 wc.hCursor = LoadCursor(
nullptr, IDC_ARROW);
210 wc.hIcon =
LoadIcon(
nullptr, IDI_APPLICATION);
211 wc.hInstance = hInstance;
212 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
213 wc.lpszClassName = TEXT(
"ANGLE-win");
214 wc.lpszMenuName =
nullptr;
215 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
217 gWC = RegisterClass(&wc);
219 SkDebugf(
"Could not register window class.\n");
223 if (!(fWindow = CreateWindow(TEXT(
"ANGLE-win"),
224 TEXT(
"The Invisible Man"),
228 hInstance,
nullptr))) {
229 SkDebugf(
"Could not create window.\n");
233 if (!(fDeviceContext = GetDC(fWindow))) {
234 SkDebugf(
"Could not get device context.\n");
235 this->destroyGLContext();
239 fDisplay = get_angle_egl_display(fDeviceContext,
type);
243 SkASSERT(EGL_NO_DISPLAY == fDisplay);
244 fDisplay = get_angle_egl_display(
reinterpret_cast<void*
>(EGL_DEFAULT_DISPLAY),
type);
247 if (EGL_NO_DISPLAY == fDisplay) {
248 SkDebugf(
"Could not create ANGLE EGL display!\n");
253 angle::GetDisplayPlatformFunc getPlatform =
reinterpret_cast<angle::GetDisplayPlatformFunc
>(
254 eglGetProcAddress(
"ANGLEGetDisplayPlatform"));
256 fResetPlatform =
reinterpret_cast<angle::ResetDisplayPlatformFunc
>(
257 eglGetProcAddress(
"ANGLEResetDisplayPlatform"));
260 angle::PlatformMethods* platformMethods =
nullptr;
261 if (getPlatform(fDisplay, angle::g_PlatformMethodNames, angle::g_NumPlatformMethods,
262 nullptr, &platformMethods)) {
263 platformMethods->addTraceEvent = ANGLE_addTraceEvent;
264 platformMethods->getTraceCategoryEnabledFlag = ANGLE_getTraceCategoryEnabledFlag;
265 platformMethods->updateTraceEventDuration = ANGLE_updateTraceEventDuration;
266 platformMethods->monotonicallyIncreasingTime = ANGLE_monotonicallyIncreasingTime;
272 if (!eglInitialize(fDisplay, &majorVersion, &minorVersion)) {
273 SkDebugf(
"Could not initialize display!");
274 this->destroyGLContext();
279 static const EGLint configAttribs[] = {
280 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
281 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
289 EGLConfig surfaceConfig;
290 if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
291 SkDebugf(
"Could not create choose config!");
292 this->destroyGLContext();
296 int versionNum = ANGLEContextVersion::kES2 ==
version ? 2 : 3;
297 std::vector<EGLint> contextAttribs = {
298 EGL_CONTEXT_CLIENT_VERSION, versionNum,
301 const char*
extensions = eglQueryString(fDisplay, EGL_EXTENSIONS);
302 if (strstr(
extensions,
"EGL_ANGLE_create_context_backwards_compatible")) {
304 contextAttribs.push_back(EGL_FALSE);
307 contextAttribs.push_back(EGL_NONE);
309 EGLContext eglShareContext = shareContext ? shareContext->fContext :
nullptr;
310 fContext = eglCreateContext(fDisplay, surfaceConfig, eglShareContext, contextAttribs.data());
312 SkDebugf(
"Could not create context!");
313 this->destroyGLContext();
317 static const EGLint surfaceAttribs[] = {
323 fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
326 if (!eglMakeCurrent(fDisplay, fSurface, fSurface,
fContext)) {
327 SkDebugf(
"Could not set the context.");
328 this->destroyGLContext();
333 if (
nullptr ==
gl.get()) {
334 SkDebugf(
"Could not create ANGLE GL interface!\n");
335 this->destroyGLContext();
338 if (!
gl->validate()) {
339 SkDebugf(
"Could not validate ANGLE GL interface!\n");
340 this->destroyGLContext();
348 const char*
renderer =
reinterpret_cast<const char*
>(rendererUByte);
350 case ANGLEBackend::kD3D9:
353 case ANGLEBackend::kD3D11:
365 fCreateImage = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress(
"eglCreateImageKHR");
366 fDestroyImage = (PFNEGLDESTROYIMAGEKHRPROC)eglGetProcAddress(
"eglDestroyImageKHR");
369 this->
init(std::move(
gl));
372ANGLEGLContext::~ANGLEGLContext() {
374 this->destroyGLContext();
378 if (!this->
gl()->hasExtension(
"EGL_KHR_gl_texture_2D_image")) {
393 if (!this->
gl()->hasExtension(
"GL_OES_EGL_image_external")) {
397 EGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
398 (EGLImageTargetTexture2DProc)eglGetProcAddress(
"glEGLImageTargetTexture2DOES");
399 if (!glEGLImageTargetTexture2D) {
420std::unique_ptr<sk_gpu_test::GLTestContext> ANGLEGLContext::makeNew()
const {
423 std::unique_ptr<sk_gpu_test::GLTestContext> ctx =
431void ANGLEGLContext::destroyGLContext() {
432 if (EGL_NO_DISPLAY != fDisplay) {
433 if (eglGetCurrentContext() ==
fContext) {
435 eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
439 eglDestroyContext(fDisplay,
fContext);
443 if (EGL_NO_SURFACE != fSurface) {
444 eglDestroySurface(fDisplay, fSurface);
445 fSurface = EGL_NO_SURFACE;
448 if (fResetPlatform) {
449 fResetPlatform(fDisplay);
458 eglTerminate(fDisplay);
460 fDisplay = EGL_NO_DISPLAY;
461 fOwnsDisplay =
false;
464#ifdef SK_BUILD_FOR_WIN
466 if (fDeviceContext) {
467 ReleaseDC(fWindow, fDeviceContext);
471 DestroyWindow(fWindow);
477void ANGLEGLContext::onPlatformMakeNotCurrent()
const {
478 if (!eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
479 SkDebugf(
"Could not reset the context 0x%x.\n", eglGetError());
483void ANGLEGLContext::onPlatformMakeCurrent()
const {
484 if (!eglMakeCurrent(fDisplay, fSurface, fSurface,
fContext)) {
485 SkDebugf(
"Could not set the context 0x%x.\n", eglGetError());
489std::function<void()> ANGLEGLContext::onPlatformGetAutoContextRestore()
const {
490 if (eglGetCurrentContext() ==
fContext) {
493 return context_restorer();
496GrGLFuncPtr ANGLEGLContext::onPlatformGetProcAddress(
const char*
name)
const {
497 return eglGetProcAddress(
name);
503 static Libs gLibs = {
nullptr,
nullptr };
505 if (
nullptr == gLibs.fGLLib) {
507#if defined(SK_BUILD_FOR_WIN)
510#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
519 if (
nullptr == gLibs.fGLLib ||
nullptr == gLibs.fEGLLib) {
529#if defined(SK_BUILD_FOR_WIN) && defined(_M_ARM64)
538#if defined(SK_BUILD_FOR_WIN)
544#if defined(SK_BUILD_FOR_MAC)
550 ANGLEGLContext* angleShareContext =
reinterpret_cast<ANGLEGLContext*
>(shareContext);
551 std::unique_ptr<GLTestContext> ctx(
new ANGLEGLContext(
type,
version,
552 angleShareContext, display));
553 if (!ctx->isValid()) {
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE
#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE
#define EGL_PLATFORM_ANGLE_ANGLE
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE
SK_API sk_sp< const GrGLInterface > GrGLMakeAssembledGLESInterface(void *ctx, GrGLGetProc get)
#define GR_EGL_GL_TEXTURE_2D
#define GR_EGL_IMAGE_PRESERVED
#define GR_EGL_GL_TEXTURE_LEVEL
#define GR_GL_TEXTURE_EXTERNAL
#define GR_GL_CALL(IFACE, X)
#define GR_GL_CALL_RET(IFACE, RET, X)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
@ kNo
Don't pre-clip the geometry before applying the (perspective) matrix.
void * SkGetProcedureAddress(void *library, const char *functionName)
void * SkLoadDynamicLibrary(const char *libraryName)
virtual void updateTraceEventDuration(const uint8_t *categoryEnabledFlag, const char *name, SkEventTracer::Handle handle)=0
virtual SkEventTracer::Handle addTraceEvent(char phase, const uint8_t *categoryEnabledFlag, const char *name, uint64_t id, int32_t numArgs, const char **argNames, const uint8_t *argTypes, const uint64_t *argValues, uint8_t flags)=0
virtual const uint8_t * getCategoryGroupEnabled(const char *name)=0
static SkEventTracer * GetInstance()
FlutterSemanticsFlag flags
Dart_NativeFunction function
sk_sp< const SkImage > image
DEF_SWITCHES_START aot vmservice shared library name
sk_sp< const GrGLInterface > CreateANGLEGLInterface()
std::unique_ptr< GLTestContext > MakeANGLETestContext(ANGLEBackend type, ANGLEContextVersion version, GLTestContext *shareContext, void *display)