2012-03-28 16:19:11 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2014-11-13 19:12:41 +00:00
|
|
|
#include "gl/angle/SkANGLEGLContext.h"
|
2012-03-28 16:19:11 +00:00
|
|
|
|
2015-02-23 18:51:13 +00:00
|
|
|
#include <EGL/egl.h>
|
2015-07-24 13:52:40 +00:00
|
|
|
#include <EGL/eglext.h>
|
2015-02-23 18:51:13 +00:00
|
|
|
|
2015-07-21 21:50:07 +00:00
|
|
|
#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
|
|
|
|
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
|
|
|
|
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
|
|
|
|
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
|
2015-02-23 16:57:23 +00:00
|
|
|
|
2015-02-23 18:51:13 +00:00
|
|
|
void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay) {
|
2015-07-24 13:52:40 +00:00
|
|
|
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
|
2015-02-23 16:57:23 +00:00
|
|
|
eglGetPlatformDisplayEXT =
|
2015-07-24 13:52:40 +00:00
|
|
|
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
|
2015-02-23 16:57:23 +00:00
|
|
|
|
|
|
|
if (!eglGetPlatformDisplayEXT) {
|
2015-02-23 18:51:13 +00:00
|
|
|
return eglGetDisplay(static_cast<EGLNativeDisplayType>(nativeDisplay));
|
2015-02-23 16:57:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Try for an ANGLE D3D11 context, fall back to D3D9.
|
|
|
|
EGLint attribs[2][3] = {
|
|
|
|
{
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
|
|
|
EGL_NONE
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
|
|
|
|
EGL_NONE
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
EGLDisplay display = EGL_NO_DISPLAY;
|
|
|
|
for (int i = 0; i < 2 && display == EGL_NO_DISPLAY; ++i) {
|
|
|
|
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
|
|
|
|
nativeDisplay, attribs[i]);
|
|
|
|
}
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
2012-03-28 16:19:11 +00:00
|
|
|
SkANGLEGLContext::SkANGLEGLContext()
|
|
|
|
: fContext(EGL_NO_CONTEXT)
|
|
|
|
, fDisplay(EGL_NO_DISPLAY)
|
|
|
|
, fSurface(EGL_NO_SURFACE) {
|
|
|
|
|
|
|
|
EGLint numConfigs;
|
|
|
|
static const EGLint configAttribs[] = {
|
|
|
|
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
|
|
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
|
|
|
EGL_RED_SIZE, 8,
|
|
|
|
EGL_GREEN_SIZE, 8,
|
|
|
|
EGL_BLUE_SIZE, 8,
|
|
|
|
EGL_ALPHA_SIZE, 8,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
|
|
|
|
2015-02-23 16:57:23 +00:00
|
|
|
fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY);
|
|
|
|
if (EGL_NO_DISPLAY == fDisplay) {
|
|
|
|
SkDebugf("Could not create EGL display!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
EGLint majorVersion;
|
|
|
|
EGLint minorVersion;
|
|
|
|
eglInitialize(fDisplay, &majorVersion, &minorVersion);
|
|
|
|
|
2012-04-02 15:04:16 +00:00
|
|
|
EGLConfig surfaceConfig;
|
|
|
|
eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs);
|
2012-03-28 16:19:11 +00:00
|
|
|
|
|
|
|
static const EGLint contextAttribs[] = {
|
|
|
|
EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
2012-04-02 15:04:16 +00:00
|
|
|
fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs);
|
2012-03-28 16:19:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
static const EGLint surfaceAttribs[] = {
|
2015-02-23 16:57:23 +00:00
|
|
|
EGL_WIDTH, 1,
|
|
|
|
EGL_HEIGHT, 1,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
|
|
|
|
2012-04-02 15:04:16 +00:00
|
|
|
fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
|
2012-03-28 16:19:11 +00:00
|
|
|
|
2012-04-02 15:04:16 +00:00
|
|
|
eglMakeCurrent(fDisplay, fSurface, fSurface, fContext);
|
2012-03-28 16:19:11 +00:00
|
|
|
|
2015-06-23 20:23:44 +00:00
|
|
|
SkAutoTUnref<const GrGLInterface> gl(GrGLCreateANGLEInterface());
|
|
|
|
if (NULL == gl.get()) {
|
2012-03-28 16:19:11 +00:00
|
|
|
SkDebugf("Could not create ANGLE GL interface!\n");
|
|
|
|
this->destroyGLContext();
|
2014-10-16 06:03:54 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-06-23 20:23:44 +00:00
|
|
|
if (!gl->validate()) {
|
2014-10-16 06:03:54 +00:00
|
|
|
SkDebugf("Could not validate ANGLE GL interface!\n");
|
|
|
|
this->destroyGLContext();
|
|
|
|
return;
|
2012-03-28 16:19:11 +00:00
|
|
|
}
|
2015-06-23 20:23:44 +00:00
|
|
|
|
|
|
|
this->init(gl.detach());
|
2014-10-16 06:03:54 +00:00
|
|
|
}
|
2012-03-28 16:19:11 +00:00
|
|
|
|
2014-10-16 06:03:54 +00:00
|
|
|
SkANGLEGLContext::~SkANGLEGLContext() {
|
2015-06-23 20:23:44 +00:00
|
|
|
this->teardown();
|
2014-10-16 06:03:54 +00:00
|
|
|
this->destroyGLContext();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkANGLEGLContext::destroyGLContext() {
|
|
|
|
if (fDisplay) {
|
|
|
|
eglMakeCurrent(fDisplay, 0, 0, 0);
|
|
|
|
|
|
|
|
if (fContext) {
|
|
|
|
eglDestroyContext(fDisplay, fContext);
|
|
|
|
fContext = EGL_NO_CONTEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fSurface) {
|
|
|
|
eglDestroySurface(fDisplay, fSurface);
|
|
|
|
fSurface = EGL_NO_SURFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO should we close the display?
|
|
|
|
fDisplay = EGL_NO_DISPLAY;
|
|
|
|
}
|
2012-03-28 16:19:11 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 20:23:44 +00:00
|
|
|
void SkANGLEGLContext::onPlatformMakeCurrent() const {
|
2012-04-02 15:04:16 +00:00
|
|
|
if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
|
2012-03-28 16:19:11 +00:00
|
|
|
SkDebugf("Could not set the context.\n");
|
|
|
|
}
|
|
|
|
}
|
2013-10-09 18:25:38 +00:00
|
|
|
|
2015-06-23 20:23:44 +00:00
|
|
|
void SkANGLEGLContext::onPlatformSwapBuffers() const {
|
2013-10-09 18:25:38 +00:00
|
|
|
if (!eglSwapBuffers(fDisplay, fSurface)) {
|
|
|
|
SkDebugf("Could not complete eglSwapBuffers.\n");
|
|
|
|
}
|
|
|
|
}
|
2015-06-23 20:23:44 +00:00
|
|
|
|
|
|
|
GrGLFuncPtr SkANGLEGLContext::onPlatformGetProcAddress(const char* name) const {
|
|
|
|
return eglGetProcAddress(name);
|
|
|
|
}
|