• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 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 #include "gl/SkNativeGLContext.h"
9 
AutoContextRestore()10 SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
11     fOldEGLContext = eglGetCurrentContext();
12     fOldDisplay = eglGetCurrentDisplay();
13     fOldSurface = eglGetCurrentSurface(EGL_DRAW);
14 
15 }
16 
~AutoContextRestore()17 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
18     if (NULL != fOldDisplay) {
19         eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext);
20     }
21 }
22 
23 ///////////////////////////////////////////////////////////////////////////////
24 
SkNativeGLContext()25 SkNativeGLContext::SkNativeGLContext()
26     : fContext(EGL_NO_CONTEXT)
27     , fDisplay(EGL_NO_DISPLAY)
28     , fSurface(EGL_NO_SURFACE) {
29 }
30 
~SkNativeGLContext()31 SkNativeGLContext::~SkNativeGLContext() {
32     this->destroyGLContext();
33 }
34 
destroyGLContext()35 void SkNativeGLContext::destroyGLContext() {
36     if (fDisplay) {
37         eglMakeCurrent(fDisplay, 0, 0, 0);
38 
39         if (fContext) {
40             eglDestroyContext(fDisplay, fContext);
41             fContext = EGL_NO_CONTEXT;
42         }
43 
44         if (fSurface) {
45             eglDestroySurface(fDisplay, fSurface);
46             fSurface = EGL_NO_SURFACE;
47         }
48 
49         //TODO should we close the display?
50         fDisplay = EGL_NO_DISPLAY;
51     }
52 }
53 
createGLContext()54 const GrGLInterface* SkNativeGLContext::createGLContext() {
55     static const EGLint kEGLContextAttribsForOpenGL[] = {
56         EGL_NONE
57     };
58 
59     static const EGLint kEGLContextAttribsForOpenGLES[] = {
60         EGL_CONTEXT_CLIENT_VERSION, 2,
61         EGL_NONE
62     };
63 
64     static const struct {
65         const EGLint* fContextAttribs;
66         EGLenum fAPI;
67         EGLint  fRenderableTypeBit;
68         GrGLBinding fBinding;
69     } kAPIs[] = {
70         {   // OpenGL
71             kEGLContextAttribsForOpenGL,
72             EGL_OPENGL_API,
73             EGL_OPENGL_BIT,
74             kDesktop_GrGLBinding
75         },
76         {   // OpenGL ES. This seems to work for both ES2 and 3 (when available).
77             kEGLContextAttribsForOpenGLES,
78             EGL_OPENGL_ES_API,
79             EGL_OPENGL_ES2_BIT,
80             kES_GrGLBinding
81         },
82     };
83 
84     const GrGLInterface* interface = NULL;
85 
86     for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) {
87         fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
88 
89         EGLint majorVersion;
90         EGLint minorVersion;
91         eglInitialize(fDisplay, &majorVersion, &minorVersion);
92 
93 #if 0
94         SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
95         SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
96         SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION));
97         SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
98 #endif
99 
100         if (!eglBindAPI(kAPIs[api].fAPI)) {
101             continue;
102         }
103 
104         EGLint numConfigs;
105         const EGLint configAttribs[] = {
106             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
107             EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit,
108             EGL_RED_SIZE, 8,
109             EGL_GREEN_SIZE, 8,
110             EGL_BLUE_SIZE, 8,
111             EGL_ALPHA_SIZE, 8,
112             EGL_NONE
113         };
114 
115         EGLConfig surfaceConfig;
116         if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
117             SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError());
118             continue;
119         }
120 
121         fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs);
122         if (EGL_NO_CONTEXT == fContext) {
123             SkDebugf("eglCreateContext failed.  EGL Error: 0x%08x\n", eglGetError());
124             continue;
125         }
126 
127         static const EGLint kSurfaceAttribs[] = {
128             EGL_WIDTH, 1,
129             EGL_HEIGHT, 1,
130             EGL_NONE
131         };
132 
133         fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs);
134         if (EGL_NO_SURFACE == fSurface) {
135             SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError());
136             this->destroyGLContext();
137             continue;
138         }
139 
140         if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
141             SkDebugf("eglMakeCurrent failed.  EGL Error: 0x%08x\n", eglGetError());
142             this->destroyGLContext();
143             continue;
144         }
145 
146         interface = GrGLCreateNativeInterface();
147         if (NULL == interface) {
148             SkDebugf("Failed to create gl interface.\n");
149             this->destroyGLContext();
150             continue;
151         }
152 
153         if (!interface->validate(kAPIs[api].fBinding)) {
154             interface->unref();
155             interface = NULL;
156             this->destroyGLContext();
157         }
158     }
159 
160     return interface;
161 }
162 
makeCurrent() const163 void SkNativeGLContext::makeCurrent() const {
164     if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
165         SkDebugf("Could not set the context.\n");
166     }
167 }
168 
swapBuffers() const169 void SkNativeGLContext::swapBuffers() const {
170     if (!eglSwapBuffers(fDisplay, fSurface)) {
171         SkDebugf("Could not complete eglSwapBuffers.\n");
172     }
173 }
174