• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2016 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #include <EGL/egl.h>
10 #include <GLES/gl.h>
11 #include "../GLWindowContext.h"
12 #include "WindowContextFactory_android.h"
13 #include "gl/GrGLInterface.h"
14 
15 using sk_app::GLWindowContext;
16 using sk_app::DisplayParams;
17 
18 namespace {
19 class GLWindowContext_android : public GLWindowContext {
20 public:
21 
22     GLWindowContext_android(ANativeWindow*, const DisplayParams&);
23 
24     ~GLWindowContext_android() override;
25 
26     void onSwapBuffers() override;
27 
28     sk_sp<const GrGLInterface> onInitializeContext() override;
29     void onDestroyContext() override;
30 
31 private:
32 
33     EGLDisplay fDisplay;
34     EGLContext fEGLContext;
35     EGLSurface fSurfaceAndroid;
36 
37     // For setDisplayParams and resize which call onInitializeContext with null platformData
38     ANativeWindow* fNativeWindow = nullptr;
39 
40     typedef GLWindowContext INHERITED;
41 };
42 
GLWindowContext_android(ANativeWindow * window,const DisplayParams & params)43 GLWindowContext_android::GLWindowContext_android(ANativeWindow* window,
44                                                  const DisplayParams& params)
45     : INHERITED(params)
46     , fDisplay(EGL_NO_DISPLAY)
47     , fEGLContext(EGL_NO_CONTEXT)
48     , fSurfaceAndroid(EGL_NO_SURFACE)
49     , fNativeWindow(window) {
50 
51     // any config code here (particularly for msaa)?
52 
53     this->initializeContext();
54 }
55 
~GLWindowContext_android()56 GLWindowContext_android::~GLWindowContext_android() {
57     this->destroyContext();
58 }
59 
onInitializeContext()60 sk_sp<const GrGLInterface> GLWindowContext_android::onInitializeContext() {
61     fWidth = ANativeWindow_getWidth(fNativeWindow);
62     fHeight = ANativeWindow_getHeight(fNativeWindow);
63 
64     fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
65 
66     EGLint majorVersion;
67     EGLint minorVersion;
68     eglInitialize(fDisplay, &majorVersion, &minorVersion);
69 
70     SkAssertResult(eglBindAPI(EGL_OPENGL_ES_API));
71 
72     EGLint numConfigs = 0;
73     EGLint eglSampleCnt = fDisplayParams.fMSAASampleCount > 1 ? fDisplayParams.fMSAASampleCount > 1
74                                                               : 0;
75     const EGLint configAttribs[] = {
76         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
77         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
78         EGL_RED_SIZE, 8,
79         EGL_GREEN_SIZE, 8,
80         EGL_BLUE_SIZE, 8,
81         EGL_ALPHA_SIZE, 8,
82         EGL_STENCIL_SIZE, 8,
83         EGL_SAMPLE_BUFFERS, eglSampleCnt ? 1 : 0,
84         EGL_SAMPLES, eglSampleCnt,
85         EGL_NONE
86     };
87 
88     EGLConfig surfaceConfig;
89     SkAssertResult(eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs));
90     SkASSERT(numConfigs > 0);
91 
92     static const EGLint kEGLContextAttribsForOpenGLES[] = {
93         EGL_CONTEXT_CLIENT_VERSION, 2,
94         EGL_NONE
95     };
96     fEGLContext = eglCreateContext(
97             fDisplay, surfaceConfig, nullptr, kEGLContextAttribsForOpenGLES);
98     SkASSERT(EGL_NO_CONTEXT != fEGLContext);
99 
100 //    SkDebugf("EGL: %d.%d", majorVersion, minorVersion);
101 //    SkDebugf("Vendor: %s", eglQueryString(fDisplay, EGL_VENDOR));
102 //    SkDebugf("Extensions: %s", eglQueryString(fDisplay, EGL_EXTENSIONS));
103 
104     fSurfaceAndroid = eglCreateWindowSurface(fDisplay, surfaceConfig, fNativeWindow, nullptr);
105     SkASSERT(EGL_NO_SURFACE != fSurfaceAndroid);
106 
107     SkAssertResult(eglMakeCurrent(fDisplay, fSurfaceAndroid, fSurfaceAndroid, fEGLContext));
108     // GLWindowContext::initializeContext will call GrGLMakeNativeInterface so we
109     // won't call it here.
110 
111     glClearStencil(0);
112     glClearColor(0, 0, 0, 0);
113     glStencilMask(0xffffffff);
114     glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
115 
116     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
117     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
118     fSampleCount = SkTMax(fSampleCount, 1);
119 
120     return GrGLMakeNativeInterface();
121 }
122 
onDestroyContext()123 void GLWindowContext_android::onDestroyContext() {
124     if (!fDisplay || !fEGLContext || !fSurfaceAndroid) {
125         return;
126     }
127     eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
128     SkAssertResult(eglDestroySurface(fDisplay, fSurfaceAndroid));
129     SkAssertResult(eglDestroyContext(fDisplay, fEGLContext));
130     fEGLContext = EGL_NO_CONTEXT;
131     fSurfaceAndroid = EGL_NO_SURFACE;
132 }
133 
onSwapBuffers()134 void GLWindowContext_android::onSwapBuffers() {
135     if (fDisplay && fEGLContext && fSurfaceAndroid) {
136         eglSwapBuffers(fDisplay, fSurfaceAndroid);
137     }
138 }
139 
140 }  // anonymous namespace
141 
142 namespace sk_app {
143 namespace window_context_factory {
144 
NewGLForAndroid(ANativeWindow * window,const DisplayParams & params)145 WindowContext* NewGLForAndroid(ANativeWindow* window, const DisplayParams& params) {
146     WindowContext* ctx = new GLWindowContext_android(window, params);
147     if (!ctx->isValid()) {
148         delete ctx;
149         return nullptr;
150     }
151     return ctx;
152 }
153 
154 }  // namespace window_context_factory
155 }  // namespace sk_app
156