• 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 <GLES/gl.h>
10 
11 #include "WindowContextFactory_android.h"
12 #include "../GLWindowContext.h"
13 #include <EGL/egl.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     void 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 void 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     const EGLint configAttribs[] = {
74         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
75         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
76         EGL_RED_SIZE, 8,
77         EGL_GREEN_SIZE, 8,
78         EGL_BLUE_SIZE, 8,
79         EGL_ALPHA_SIZE, 8,
80         EGL_STENCIL_SIZE, 8,
81         EGL_SAMPLE_BUFFERS, fDisplayParams.fMSAASampleCount ? 1 : 0,
82         EGL_SAMPLES, fDisplayParams.fMSAASampleCount,
83         EGL_NONE
84     };
85 
86     EGLConfig surfaceConfig;
87     SkAssertResult(eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs));
88     SkASSERT(numConfigs > 0);
89 
90     static const EGLint kEGLContextAttribsForOpenGLES[] = {
91         EGL_CONTEXT_CLIENT_VERSION, 2,
92         EGL_NONE
93     };
94     fEGLContext = eglCreateContext(
95             fDisplay, surfaceConfig, nullptr, kEGLContextAttribsForOpenGLES);
96     SkASSERT(EGL_NO_CONTEXT != fEGLContext);
97 
98 //    SkDebugf("EGL: %d.%d", majorVersion, minorVersion);
99 //    SkDebugf("Vendor: %s", eglQueryString(fDisplay, EGL_VENDOR));
100 //    SkDebugf("Extensions: %s", eglQueryString(fDisplay, EGL_EXTENSIONS));
101 
102     // These values are the same as the corresponding VG colorspace attributes,
103     // which were accepted starting in EGL 1.2. For some reason in 1.4, sRGB
104     // became hidden behind an extension, but it looks like devices aren't
105     // advertising that extension (including Nexus 5X). So just check version?
106     const EGLint srgbWindowAttribs[] = {
107         /*EGL_GL_COLORSPACE_KHR*/ 0x309D, /*EGL_GL_COLORSPACE_SRGB_KHR*/ 0x3089,
108         EGL_NONE,
109     };
110     const EGLint* windowAttribs = nullptr;
111     auto srgbColorSpace = SkColorSpace::MakeSRGB();
112     if (srgbColorSpace == fDisplayParams.fColorSpace && majorVersion == 1 && minorVersion >= 2) {
113         windowAttribs = srgbWindowAttribs;
114     }
115 
116     fSurfaceAndroid = eglCreateWindowSurface(fDisplay, surfaceConfig, fNativeWindow, windowAttribs);
117     if (EGL_NO_SURFACE == fSurfaceAndroid && windowAttribs) {
118         // Try again without sRGB
119         fSurfaceAndroid = eglCreateWindowSurface(fDisplay, surfaceConfig, fNativeWindow, nullptr);
120     }
121     SkASSERT(EGL_NO_SURFACE != fSurfaceAndroid);
122 
123     SkAssertResult(eglMakeCurrent(fDisplay, fSurfaceAndroid, fSurfaceAndroid, fEGLContext));
124     // GLWindowContext::initializeContext will call GrGLCreateNativeInterface so we
125     // won't call it here.
126 
127     glClearStencil(0);
128     glClearColor(0, 0, 0, 0);
129     glStencilMask(0xffffffff);
130     glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
131 
132     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
133     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
134 }
135 
onDestroyContext()136 void GLWindowContext_android::onDestroyContext() {
137     if (!fDisplay || !fEGLContext || !fSurfaceAndroid) {
138         return;
139     }
140     eglMakeCurrent(fDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
141     SkAssertResult(eglDestroySurface(fDisplay, fSurfaceAndroid));
142     SkAssertResult(eglDestroyContext(fDisplay, fEGLContext));
143     fEGLContext = EGL_NO_CONTEXT;
144     fSurfaceAndroid = EGL_NO_SURFACE;
145 }
146 
onSwapBuffers()147 void GLWindowContext_android::onSwapBuffers() {
148     if (fDisplay && fEGLContext && fSurfaceAndroid) {
149         eglSwapBuffers(fDisplay, fSurfaceAndroid);
150     }
151 }
152 
153 }  // anonymous namespace
154 
155 namespace sk_app {
156 namespace window_context_factory {
157 
NewGLForAndroid(ANativeWindow * window,const DisplayParams & params)158 WindowContext* NewGLForAndroid(ANativeWindow* window, const DisplayParams& params) {
159     WindowContext* ctx = new GLWindowContext_android(window, params);
160     if (!ctx->isValid()) {
161         delete ctx;
162         return nullptr;
163     }
164     return ctx;
165 }
166 
167 }  // namespace window_context_factory
168 }  // namespace sk_app
169