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-11-22 22:51:00 +00:00
|
|
|
#include "gl/GrGLDefines.h"
|
|
|
|
#include "gl/GrGLUtil.h"
|
|
|
|
|
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-09-11 20:07:29 +00:00
|
|
|
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
|
2015-02-23 16:57:23 +00:00
|
|
|
|
2015-09-11 20:07:29 +00:00
|
|
|
void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay, bool useGLBackend) {
|
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
|
|
|
}
|
|
|
|
|
|
|
|
EGLDisplay display = EGL_NO_DISPLAY;
|
2015-09-11 20:07:29 +00:00
|
|
|
if (useGLBackend) {
|
|
|
|
// Try for an ANGLE D3D11 context, fall back to D3D9.
|
|
|
|
EGLint attribs[3] = {
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,
|
|
|
|
EGL_NONE
|
|
|
|
};
|
2015-11-22 22:51:00 +00:00
|
|
|
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs);
|
2015-09-11 20:07:29 +00:00
|
|
|
} else {
|
|
|
|
// Try for an ANGLE D3D11 context, fall back to D3D9, and finally GL.
|
|
|
|
EGLint attribs[3][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
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
|
|
|
EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,
|
|
|
|
EGL_NONE
|
|
|
|
}
|
|
|
|
};
|
|
|
|
for (int i = 0; i < 3 && display == EGL_NO_DISPLAY; ++i) {
|
2015-11-22 22:51:00 +00:00
|
|
|
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,nativeDisplay, attribs[i]);
|
2015-09-11 20:07:29 +00:00
|
|
|
}
|
2015-02-23 16:57:23 +00:00
|
|
|
}
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
2015-09-11 20:07:29 +00:00
|
|
|
SkANGLEGLContext::SkANGLEGLContext(bool useGLBackend)
|
2012-03-28 16:19:11 +00:00
|
|
|
: 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-11-22 22:51:00 +00:00
|
|
|
fIsGLBackend = useGLBackend;
|
2015-09-11 20:07:29 +00:00
|
|
|
fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY, useGLBackend);
|
2015-02-23 16:57:23 +00:00
|
|
|
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
|
|
|
|
};
|
2015-08-27 14:41:13 +00:00
|
|
|
fContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, 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());
|
2015-08-27 14:41:13 +00:00
|
|
|
if (nullptr == 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();
|
|
|
|
}
|
|
|
|
|
2015-11-22 22:51:00 +00:00
|
|
|
GrEGLImage SkANGLEGLContext::texture2DToEGLImage(GrGLuint texID) const {
|
|
|
|
if (!this->gl()->hasExtension("EGL_KHR_gl_texture_2D_image")) {
|
|
|
|
return GR_EGL_NO_IMAGE;
|
|
|
|
}
|
|
|
|
GrEGLImage img;
|
|
|
|
GrEGLint attribs[] = { GR_EGL_GL_TEXTURE_LEVEL, 0,
|
|
|
|
GR_EGL_IMAGE_PRESERVED, GR_EGL_TRUE,
|
|
|
|
GR_EGL_NONE };
|
|
|
|
// 64 bit cast is to shut Visual C++ up about casting 32 bit value to a pointer.
|
|
|
|
GrEGLClientBuffer clientBuffer = reinterpret_cast<GrEGLClientBuffer>((uint64_t)texID);
|
|
|
|
GR_GL_CALL_RET(this->gl(), img,
|
|
|
|
EGLCreateImage(fDisplay, fContext, GR_EGL_GL_TEXTURE_2D, clientBuffer,
|
|
|
|
attribs));
|
|
|
|
return img;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SkANGLEGLContext::destroyEGLImage(GrEGLImage image) const {
|
|
|
|
GR_GL_CALL(this->gl(), EGLDestroyImage(fDisplay, image));
|
|
|
|
}
|
|
|
|
|
|
|
|
GrGLuint SkANGLEGLContext::eglImageToExternalTexture(GrEGLImage image) const {
|
|
|
|
GrGLClearErr(this->gl());
|
|
|
|
if (!this->gl()->hasExtension("GL_OES_EGL_image_external")) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
GrGLEGLImageTargetTexture2DProc glEGLImageTargetTexture2D =
|
|
|
|
(GrGLEGLImageTargetTexture2DProc)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
|
|
|
if (!glEGLImageTargetTexture2D) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
GrGLuint texID;
|
|
|
|
GR_GL_CALL(this->gl(), GenTextures(1, &texID));
|
|
|
|
if (!texID) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
GR_GL_CALL(this->gl(), BindTexture(GR_GL_TEXTURE_EXTERNAL, texID));
|
|
|
|
if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
|
|
|
|
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
glEGLImageTargetTexture2D(GR_GL_TEXTURE_EXTERNAL, image);
|
|
|
|
if (GR_GL_GET_ERROR(this->gl()) != GR_GL_NO_ERROR) {
|
|
|
|
GR_GL_CALL(this->gl(), DeleteTextures(1, &texID));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return texID;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkGLContext* SkANGLEGLContext::createNew() const {
|
Revert of Add config options to run different GPU APIs to dm and nanobench (patchset #21 id:400001 of https://codereview.chromium.org/1490113005/ )
Reason for revert:
The Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug builder fails after this CL.
Links to specific builds:
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1689
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1690
http://build.chromium.org/p/client.skia/builders/Test-Win8-MSVC-ShuttleB-GPU-HD4600-x86_64-Debug/builds/1691
Original issue's description:
> Add config options to run different GPU APIs to dm and nanobench
>
> Add extended config specification form that can be used to run different
> gpu backend with different APIs.
>
> The configs can be specified with the form:
> gpu(api=string,dit=bool,nvpr=bool,samples=int)
>
> This replaces and removes the --gpuAPI flag.
>
> All existing configs should still work.
>
> Adds following documentation:
>
> out/Debug/dm --help config
>
> Flags:
> --config: type: string default: 565 8888 gpu nonrendering
> Options: 565 8888 debug gpu gpudebug gpudft gpunull msaa16 msaa4
> nonrendering null nullgpu nvprmsaa16 nvprmsaa4 pdf pdf_poppler skp svg
> xps or use extended form 'backend(option=value,...)'.
>
> Extended form: 'backend(option=value,...)'
>
> Possible backends and options:
>
> gpu(api=string,dit=bool,nvpr=bool,samples=int) GPU backend
> api type: string default: native.
> Select graphics API to use with gpu backend.
> Options:
> native Use platform default OpenGL or OpenGL ES backend.
> gl Use OpenGL.
> gles Use OpenGL ES.
> debug Use debug OpenGL.
> null Use null OpenGL.
> dit type: bool default: false.
> Use device independent text.
> nvpr type: bool default: false.
> Use NV_path_rendering OpenGL and OpenGL ES extension.
> samples type: int default: 0.
> Use multisampling with N samples.
>
> Predefined configs:
>
> gpu = gpu()
> msaa4 = gpu(samples=4)
> msaa16 = gpu(samples=16)
> nvprmsaa4 = gpu(nvpr=true,samples=4)
> nvprmsaa16 = gpu(nvpr=true,samples=16)
> gpudft = gpu(dit=true)
> gpudebug = gpu(api=debug)
> gpunull = gpu(api=null)
> debug = gpu(api=debug)
> nullgpu = gpu(api=null)
>
> BUG=skia:2992
>
> Committed: https://skia.googlesource.com/skia/+/e13ca329fca4c28cf4e078561f591ab27b743d23
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1490113005
>
> Committed: https://skia.googlesource.com/skia/+/c8b4336444e7b90382e04e33665fb3b8490b825b
>
> Committed: https://skia.googlesource.com/skia/+/9ebc3f0ee6db215dde461dc4777d85988cf272dd
TBR=mtklein@google.com,bsalomon@google.com,joshualitt@google.com,scroggo@google.com,kkinnunen@nvidia.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:2992
Review URL: https://codereview.chromium.org/1548683002
2015-12-22 18:22:26 +00:00
|
|
|
SkGLContext* ctx = SkANGLEGLContext::Create(this->gl()->fStandard, fIsGLBackend);
|
2015-11-22 22:51:00 +00:00
|
|
|
if (ctx) {
|
|
|
|
ctx->makeCurrent();
|
|
|
|
}
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2014-10-16 06:03:54 +00:00
|
|
|
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);
|
|
|
|
}
|