3 * Copyright 2016 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
11 #include "include/gpu/gl/GrGLInterface.h"
12 #include "tools/sk_app/GLWindowContext.h"
13 #include "tools/sk_app/android/WindowContextFactory_android.h"
15 using sk_app::GLWindowContext;
16 using sk_app::DisplayParams;
19 class GLWindowContext_android : public GLWindowContext {
22 GLWindowContext_android(ANativeWindow*, const DisplayParams&);
24 ~GLWindowContext_android() override;
26 void onSwapBuffers() override;
28 sk_sp<const GrGLInterface> onInitializeContext() override;
29 void onDestroyContext() override;
34 EGLContext fEGLContext;
35 EGLSurface fSurfaceAndroid;
37 // For setDisplayParams and resize which call onInitializeContext with null platformData
38 ANativeWindow* fNativeWindow = nullptr;
40 using INHERITED = GLWindowContext;
43 GLWindowContext_android::GLWindowContext_android(ANativeWindow* window,
44 const DisplayParams& params)
46 , fDisplay(EGL_NO_DISPLAY)
47 , fEGLContext(EGL_NO_CONTEXT)
48 , fSurfaceAndroid(EGL_NO_SURFACE)
49 , fNativeWindow(window) {
51 // any config code here (particularly for msaa)?
53 this->initializeContext();
56 GLWindowContext_android::~GLWindowContext_android() {
57 this->destroyContext();
60 sk_sp<const GrGLInterface> GLWindowContext_android::onInitializeContext() {
61 fWidth = ANativeWindow_getWidth(fNativeWindow);
62 fHeight = ANativeWindow_getHeight(fNativeWindow);
64 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
68 eglInitialize(fDisplay, &majorVersion, &minorVersion);
70 SkAssertResult(eglBindAPI(EGL_OPENGL_ES_API));
72 EGLint numConfigs = 0;
73 EGLint eglSampleCnt = fDisplayParams.fMSAASampleCount > 1 ? fDisplayParams.fMSAASampleCount > 1
75 const EGLint configAttribs[] = {
76 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
77 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
83 EGL_SAMPLE_BUFFERS, eglSampleCnt ? 1 : 0,
84 EGL_SAMPLES, eglSampleCnt,
88 EGLConfig surfaceConfig;
89 SkAssertResult(eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs));
90 SkASSERT(numConfigs > 0);
92 static const EGLint kEGLContextAttribsForOpenGLES[] = {
93 EGL_CONTEXT_CLIENT_VERSION, 2,
96 fEGLContext = eglCreateContext(
97 fDisplay, surfaceConfig, nullptr, kEGLContextAttribsForOpenGLES);
98 SkASSERT(EGL_NO_CONTEXT != fEGLContext);
100 // SkDebugf("EGL: %d.%d", majorVersion, minorVersion);
101 // SkDebugf("Vendor: %s", eglQueryString(fDisplay, EGL_VENDOR));
102 // SkDebugf("Extensions: %s", eglQueryString(fDisplay, EGL_EXTENSIONS));
104 fSurfaceAndroid = eglCreateWindowSurface(fDisplay, surfaceConfig, fNativeWindow, nullptr);
105 SkASSERT(EGL_NO_SURFACE != fSurfaceAndroid);
107 SkAssertResult(eglMakeCurrent(fDisplay, fSurfaceAndroid, fSurfaceAndroid, fEGLContext));
108 // GLWindowContext::initializeContext will call GrGLMakeNativeInterface so we
109 // won't call it here.
112 glClearColor(0, 0, 0, 0);
113 glStencilMask(0xffffffff);
114 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
116 eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
117 eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
118 fSampleCount = std::max(fSampleCount, 1);
120 eglSwapInterval(fDisplay, fDisplayParams.fDisableVsync ? 0 : 1);
122 return GrGLMakeNativeInterface();
125 void GLWindowContext_android::onDestroyContext() {
126 if (!fDisplay || !fEGLContext || !fSurfaceAndroid) {
129 eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
130 SkAssertResult(eglDestroySurface(fDisplay, fSurfaceAndroid));
131 SkAssertResult(eglDestroyContext(fDisplay, fEGLContext));
132 fEGLContext = EGL_NO_CONTEXT;
133 fSurfaceAndroid = EGL_NO_SURFACE;
136 void GLWindowContext_android::onSwapBuffers() {
137 if (fDisplay && fEGLContext && fSurfaceAndroid) {
138 eglSwapBuffers(fDisplay, fSurfaceAndroid);
142 } // anonymous namespace
145 namespace window_context_factory {
147 std::unique_ptr<WindowContext> MakeGLForAndroid(ANativeWindow* window,
148 const DisplayParams& params) {
149 std::unique_ptr<WindowContext> ctx(new GLWindowContext_android(window, params));
150 if (!ctx->isValid()) {
156 } // namespace window_context_factory
157 } // namespace sk_app