mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-07 06:09:57 +03:00
This code shares the Window and EGL logic between the two projects. BUG=angle:730 Change-Id: I8940371226a8f7b02579c332f51679c4a5d0e2a5 Reviewed-on: https://chromium-review.googlesource.com/212799 Tested-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Brandon Jones <bajones@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
188 lines
4.1 KiB
C++
188 lines
4.1 KiB
C++
//
|
|
// Copyright (c) 2013 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.
|
|
//
|
|
|
|
#include <cassert>
|
|
|
|
#include "EGLWindow.h"
|
|
#include "OSWindow.h"
|
|
|
|
#ifdef _WIN32
|
|
#include "win32/Win32Timer.h"
|
|
#include "win32/Win32Window.h"
|
|
#else
|
|
#error unsupported OS.
|
|
#endif
|
|
|
|
EGLWindow::EGLWindow(size_t width, size_t height,
|
|
EGLint glesMajorVersion, EGLint requestedRenderer)
|
|
: mSurface(EGL_NO_SURFACE),
|
|
mContext(EGL_NO_CONTEXT),
|
|
mDisplay(EGL_NO_DISPLAY),
|
|
mClientVersion(glesMajorVersion),
|
|
mRequestedRenderer(requestedRenderer),
|
|
mWidth(width),
|
|
mHeight(height),
|
|
mOSWindow(CreateOSWindow())
|
|
{
|
|
}
|
|
|
|
EGLWindow::~EGLWindow()
|
|
{
|
|
destroyGL();
|
|
}
|
|
|
|
void EGLWindow::swap()
|
|
{
|
|
eglSwapBuffers(mDisplay, mSurface);
|
|
}
|
|
|
|
OSWindow *EGLWindow::getWindow() const
|
|
{
|
|
return mOSWindow.get();
|
|
}
|
|
|
|
EGLConfig EGLWindow::getConfig() const
|
|
{
|
|
return mConfig;
|
|
}
|
|
|
|
EGLDisplay EGLWindow::getDisplay() const
|
|
{
|
|
return mDisplay;
|
|
}
|
|
|
|
EGLSurface EGLWindow::getSurface() const
|
|
{
|
|
return mSurface;
|
|
}
|
|
|
|
EGLContext EGLWindow::getContext() const
|
|
{
|
|
return mContext;
|
|
}
|
|
|
|
bool EGLWindow::initializeGL()
|
|
{
|
|
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
|
if (!eglGetPlatformDisplayEXT)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
const EGLint displayAttributes[] =
|
|
{
|
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE, mRequestedRenderer,
|
|
EGL_NONE,
|
|
};
|
|
|
|
mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, mOSWindow->getNativeDisplay(), displayAttributes);
|
|
if (mDisplay == EGL_NO_DISPLAY)
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
EGLint majorVersion, minorVersion;
|
|
if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
eglBindAPI(EGL_OPENGL_ES_API);
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
const EGLint configAttributes[] =
|
|
{
|
|
EGL_RED_SIZE, 8,
|
|
EGL_GREEN_SIZE, 8,
|
|
EGL_BLUE_SIZE, 8,
|
|
EGL_ALPHA_SIZE, 8,
|
|
EGL_DEPTH_SIZE, 24,
|
|
EGL_STENCIL_SIZE, 8,
|
|
EGL_SAMPLE_BUFFERS, EGL_DONT_CARE,
|
|
EGL_NONE
|
|
};
|
|
|
|
EGLint configCount;
|
|
if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
const EGLint surfaceAttributes[] =
|
|
{
|
|
EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_TRUE,
|
|
EGL_NONE, EGL_NONE,
|
|
};
|
|
|
|
mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), surfaceAttributes);
|
|
if (mSurface == EGL_NO_SURFACE)
|
|
{
|
|
eglGetError(); // Clear error and try again
|
|
mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
|
|
}
|
|
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
EGLint contextAttibutes[] =
|
|
{
|
|
EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
|
|
EGL_NONE
|
|
};
|
|
mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
|
|
if (eglGetError() != EGL_SUCCESS)
|
|
{
|
|
destroyGL();
|
|
return false;
|
|
}
|
|
|
|
// Turn off vsync
|
|
eglSwapInterval(mDisplay, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
void EGLWindow::destroyGL()
|
|
{
|
|
if (mSurface != EGL_NO_SURFACE)
|
|
{
|
|
assert(mDisplay != EGL_NO_DISPLAY);
|
|
eglDestroySurface(mDisplay, mSurface);
|
|
mSurface = EGL_NO_SURFACE;
|
|
}
|
|
|
|
if (mContext != EGL_NO_CONTEXT)
|
|
{
|
|
assert(mDisplay != EGL_NO_DISPLAY);
|
|
eglDestroyContext(mDisplay, mContext);
|
|
mContext = EGL_NO_CONTEXT;
|
|
}
|
|
|
|
if (mDisplay != EGL_NO_DISPLAY)
|
|
{
|
|
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
eglTerminate(mDisplay);
|
|
mDisplay = EGL_NO_DISPLAY;
|
|
}
|
|
}
|