blob: 259eb5e2781616be8fe8d4244f39a6786011442b [file] [log] [blame]
/*
* Copyright 2023 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tools/window/ANGLEWindowContext.h"
#include "include/gpu/gl/GrGLAssembleInterface.h"
#include "src/gpu/ganesh/gl/GrGLDefines.h"
namespace skwindow::internal {
ANGLEWindowContext::~ANGLEWindowContext() { this->destroyContext(); }
sk_sp<const GrGLInterface> ANGLEWindowContext::onInitializeContext() {
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT");
// We expect ANGLE to support this extension
if (!eglGetPlatformDisplayEXT) {
return nullptr;
}
fDisplay = this->onGetEGLDisplay(eglGetPlatformDisplayEXT);
if (EGL_NO_DISPLAY == fDisplay) {
return nullptr;
}
EGLint majorVersion;
EGLint minorVersion;
if (!eglInitialize(fDisplay, &majorVersion, &minorVersion)) {
SkDebugf("Could not initialize display!\n");
return nullptr;
}
EGLint numConfigs;
fSampleCount = this->getDisplayParams().fMSAASampleCount;
const int sampleBuffers = fSampleCount > 1 ? 1 : 0;
const int eglSampleCnt = fSampleCount > 1 ? fSampleCount : 0;
const EGLint configAttribs[] = {EGL_RENDERABLE_TYPE,
// We currently only support ES3.
EGL_OPENGL_ES3_BIT,
EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_ALPHA_SIZE,
8,
EGL_SAMPLE_BUFFERS,
sampleBuffers,
EGL_SAMPLES,
eglSampleCnt,
EGL_NONE};
EGLConfig surfaceConfig;
if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
SkDebugf("Could not create choose config!\n");
return nullptr;
}
// We currently only support ES3.
const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
fEGLContext = eglCreateContext(fDisplay, surfaceConfig, nullptr, contextAttribs);
if (EGL_NO_CONTEXT == fEGLContext) {
SkDebugf("Could not create context!\n");
return nullptr;
}
fEGLSurface =
eglCreateWindowSurface(fDisplay, surfaceConfig, this->onGetNativeWindow(), nullptr);
if (EGL_NO_SURFACE == fEGLSurface) {
SkDebugf("Could not create surface!\n");
return nullptr;
}
if (!eglMakeCurrent(fDisplay, fEGLSurface, fEGLSurface, fEGLContext)) {
SkDebugf("Could not make context current!\n");
return nullptr;
}
sk_sp<const GrGLInterface> interface(GrGLMakeAssembledInterface(
nullptr,
[](void* ctx, const char name[]) -> GrGLFuncPtr { return eglGetProcAddress(name); }));
if (interface) {
interface->fFunctions.fClearStencil(0);
interface->fFunctions.fClearColor(0, 0, 0, 0);
interface->fFunctions.fStencilMask(0xffffffff);
interface->fFunctions.fClear(GR_GL_STENCIL_BUFFER_BIT | GR_GL_COLOR_BUFFER_BIT);
fStencilBits = this->onGetStencilBits();
SkISize size = this->onGetSize();
fWidth = size.width();
fHeight = size.height();
interface->fFunctions.fViewport(0, 0, fWidth, fHeight);
}
return interface;
}
void ANGLEWindowContext::onDestroyContext() {
eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (EGL_NO_CONTEXT != fEGLContext) {
eglDestroyContext(fDisplay, fEGLContext);
}
if (EGL_NO_SURFACE != fEGLSurface) {
eglDestroySurface(fDisplay, fEGLSurface);
}
if (EGL_NO_DISPLAY != fDisplay) {
eglTerminate(fDisplay);
}
}
void ANGLEWindowContext::onSwapBuffers() {
if (!eglSwapBuffers(fDisplay, fEGLSurface)) {
SkDebugf("Could not complete eglSwapBuffers.\n");
}
}
} // namespace skwindow::internal