OLD | NEW |
---|---|
(Empty) | |
1 | |
2 /* | |
3 * Copyright 2015 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 <EGL/egl.h> | |
9 | |
10 #include "SkOnce.h" | |
11 #include "gl/GrGLInterface.h" | |
12 #include "gl/GrGLAssembleInterface.h" | |
13 #include "gl/command_buffer/SkCommandBufferGLContext.h" | |
14 | |
15 typedef EGLDisplay (*GetDisplayProc)(EGLNativeDisplayType display_id); | |
16 typedef EGLBoolean (*InitializeProc)(EGLDisplay dpy, EGLint *major, EGLint *mino r); | |
17 typedef EGLBoolean (*TerminateProc)(EGLDisplay dpy); | |
18 typedef EGLBoolean (*ChooseConfigProc)(EGLDisplay dpy, const EGLint* attrib_list , EGLConfig* configs, EGLint config_size, EGLint* num_config); | |
19 typedef EGLBoolean (*GetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint a ttribute, EGLint* value); | |
20 typedef EGLSurface (*CreateWindowSurfaceProc)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list); | |
21 typedef EGLSurface (*CreatePbufferSurfaceProc)(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list); | |
22 typedef EGLBoolean (*DestroySurfaceProc)(EGLDisplay dpy, EGLSurface surface); | |
23 typedef EGLContext (*CreateContextProc)(EGLDisplay dpy, EGLConfig config, EGLCon text share_context, const EGLint* attrib_list); | |
24 typedef EGLBoolean (*DestroyContextProc)(EGLDisplay dpy, EGLContext ctx); | |
25 typedef EGLBoolean (*MakeCurrentProc)(EGLDisplay dpy, EGLSurface draw, EGLSurfac e read, EGLContext ctx); | |
26 typedef EGLBoolean (*SwapBuffersProc)(EGLDisplay dpy, EGLSurface surface); | |
27 typedef __eglMustCastToProperFunctionPointerType (*GetProcAddressProc)(const cha r* procname); | |
28 | |
29 static GetDisplayProc gfGetDisplay = nullptr; | |
30 static InitializeProc gfInitialize = nullptr; | |
31 static TerminateProc gfTerminate = nullptr; | |
32 static ChooseConfigProc gfChooseConfig = nullptr; | |
33 static GetConfigAttrib gfGetConfigAttrib = nullptr; | |
34 static CreateWindowSurfaceProc gfCreateWindowSurface = nullptr; | |
35 static CreatePbufferSurfaceProc gfCreatePbufferSurface = nullptr; | |
36 static DestroySurfaceProc gfDestroySurface = nullptr; | |
37 static CreateContextProc gfCreateContext = nullptr; | |
38 static DestroyContextProc gfDestroyContext = nullptr; | |
39 static MakeCurrentProc gfMakeCurrent = nullptr; | |
40 static SwapBuffersProc gfSwapBuffers = nullptr; | |
41 static GetProcAddressProc gfGetProcAddress = nullptr; | |
42 | |
43 static HMODULE ghLibrary = nullptr; | |
44 static bool gfFunctionsLoadedSuccessfully = false; | |
45 | |
46 static void LoadCommandBufferFunctions() | |
bsalomon
2015/08/27 13:47:13
hacker_style_for_nonclass_statics
hendrikw
2015/08/27 14:41:58
Done.
| |
47 { | |
bsalomon
2015/08/27 13:47:13
{ on prev line
hendrikw
2015/08/27 14:41:58
Done.
| |
48 if (!ghLibrary) { | |
49 ghLibrary = LoadLibrary("command_buffer_gles2.dll"); | |
50 | |
51 if (ghLibrary) { | |
52 gfGetDisplay = (GetDisplayProc)::GetProcAddress(ghLibrary, "CommandB uffer_GetDisplay"); | |
53 gfInitialize = (InitializeProc)::GetProcAddress(ghLibrary, "CommandB uffer_Initialize"); | |
54 gfTerminate = (TerminateProc)::GetProcAddress(ghLibrary, "CommandBuf fer_Terminate"); | |
55 gfChooseConfig = (ChooseConfigProc)::GetProcAddress(ghLibrary, "Comm andBuffer_ChooseConfig"); | |
56 gfGetConfigAttrib = (GetConfigAttrib)::GetProcAddress(ghLibrary, "Co mmandBuffer_GetConfigAttrib"); | |
57 gfCreateWindowSurface = (CreateWindowSurfaceProc)::GetProcAddress(gh Library, "CommandBuffer_CreateWindowSurface"); | |
58 gfCreatePbufferSurface = (CreatePbufferSurfaceProc)::GetProcAddress( ghLibrary, "CommandBuffer_CreatePbufferSurface"); | |
59 gfDestroySurface = (DestroySurfaceProc)::GetProcAddress(ghLibrary, " CommandBuffer_DestroySurface"); | |
60 gfCreateContext = (CreateContextProc)::GetProcAddress(ghLibrary, "Co mmandBuffer_CreateContext"); | |
61 gfDestroyContext = (DestroyContextProc)::GetProcAddress(ghLibrary, " CommandBuffer_DestroyContext"); | |
62 gfMakeCurrent = (MakeCurrentProc)::GetProcAddress(ghLibrary, "Comman dBuffer_MakeCurrent"); | |
63 gfSwapBuffers = (SwapBuffersProc)::GetProcAddress(ghLibrary, "Comman dBuffer_SwapBuffers"); | |
64 gfGetProcAddress = (GetProcAddressProc)::GetProcAddress(ghLibrary, " CommandBuffer_GetProcAddress"); | |
65 | |
66 gfFunctionsLoadedSuccessfully = gfGetDisplay && gfInitialize && gfTe rminate && | |
67 gfChooseConfig && gfCreateWindowSurf ace && | |
68 gfCreatePbufferSurface && gfDestroyS urface && | |
69 gfCreateContext && gfDestroyContext && gfMakeCurrent && | |
70 gfSwapBuffers && gfGetProcAddress; | |
71 | |
72 } | |
73 } | |
74 } | |
75 | |
76 static GrGLFuncPtr command_buffer_get_gl_proc(void* ctx, const char name[]) { | |
77 GrGLFuncPtr proc = (GrGLFuncPtr) GetProcAddress((HMODULE)ctx, name); | |
78 if (proc) { | |
79 return proc; | |
80 } | |
81 if (!gfFunctionsLoadedSuccessfully) { | |
82 return nullptr; | |
83 } | |
84 return gfGetProcAddress(name); | |
85 } | |
86 | |
87 SK_DECLARE_STATIC_ONCE(loadCommandBufferOnce); | |
88 void LoadCommandBufferOnce() { | |
89 SkOnce(&loadCommandBufferOnce, LoadCommandBufferFunctions); | |
90 } | |
91 | |
92 const GrGLInterface* GrGLCreateCommandBufferInterface() { | |
93 LoadCommandBufferOnce(); | |
94 if (!gfFunctionsLoadedSuccessfully) { | |
95 return nullptr; | |
96 } | |
97 return GrGLAssembleGLESInterface(ghLibrary, command_buffer_get_gl_proc); | |
98 } | |
99 | |
100 SkCommandBufferGLContext::SkCommandBufferGLContext() | |
101 : fContext(EGL_NO_CONTEXT) | |
102 , fDisplay(EGL_NO_DISPLAY) | |
103 , fSurface(EGL_NO_SURFACE) { | |
104 | |
105 static const EGLint configAttribs[] = { | |
106 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | |
107 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
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 static const EGLint surfaceAttribs[] = { | |
116 EGL_WIDTH, 1, | |
117 EGL_HEIGHT, 1, | |
118 EGL_NONE | |
119 }; | |
120 | |
121 initializeGLContext(nullptr, configAttribs, surfaceAttribs); | |
122 } | |
123 | |
124 SkCommandBufferGLContext::SkCommandBufferGLContext(void* nativeWindow, int msaaS ampleCount) { | |
125 static const EGLint surfaceAttribs[] = { EGL_NONE }; | |
126 | |
127 EGLint configAttribs[] = { | |
128 EGL_RED_SIZE, 8, | |
129 EGL_GREEN_SIZE, 8, | |
130 EGL_BLUE_SIZE, 8, | |
131 EGL_ALPHA_SIZE, 8, | |
132 EGL_DEPTH_SIZE, 8, | |
133 EGL_STENCIL_SIZE, 8, | |
134 EGL_SAMPLE_BUFFERS, 1, | |
135 EGL_SAMPLES, msaaSampleCount, | |
136 EGL_NONE | |
137 }; | |
138 if (msaaSampleCount == 0) { | |
139 configAttribs[12] = EGL_NONE; | |
140 } | |
141 | |
142 initializeGLContext(nativeWindow, configAttribs, surfaceAttribs); | |
143 } | |
144 | |
145 void SkCommandBufferGLContext::initializeGLContext(void* nativeWindow, const int * configAttribs, | |
146 const int* surfaceAttribs) { | |
147 LoadCommandBufferOnce(); | |
148 if (!gfFunctionsLoadedSuccessfully) { | |
149 return; | |
150 } | |
151 | |
152 fDisplay = gfGetDisplay(static_cast<EGLNativeDisplayType>(EGL_DEFAULT_DISPLA Y)); | |
153 if (EGL_NO_DISPLAY == fDisplay) { | |
154 SkDebugf("Could not create EGL display!"); | |
155 return; | |
156 } | |
157 | |
158 EGLint majorVersion; | |
159 EGLint minorVersion; | |
160 gfInitialize(fDisplay, &majorVersion, &minorVersion); | |
161 | |
162 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); | |
163 EGLint numConfigs; | |
164 gfChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); | |
165 | |
166 if (nativeWindow) { | |
167 fSurface = gfCreateWindowSurface(fDisplay, surfaceConfig, | |
168 (EGLNativeWindowType)nativeWindow, surf aceAttribs); | |
169 } else { | |
170 fSurface = gfCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttrib s); | |
171 } | |
172 | |
173 static const EGLint contextAttribs[] = { | |
174 EGL_CONTEXT_CLIENT_VERSION, 2, | |
175 EGL_NONE | |
176 }; | |
177 fContext = gfCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); | |
178 | |
179 gfMakeCurrent(fDisplay, fSurface, fSurface, fContext); | |
180 | |
181 SkAutoTUnref<const GrGLInterface> gl(GrGLCreateCommandBufferInterface()); | |
182 if (NULL == gl.get()) { | |
183 SkDebugf("Could not create CommandBuffer GL interface!\n"); | |
184 this->destroyGLContext(); | |
185 return; | |
186 } | |
187 if (!gl->validate()) { | |
188 SkDebugf("Could not validate CommandBuffer GL interface!\n"); | |
189 this->destroyGLContext(); | |
190 return; | |
191 } | |
192 | |
193 this->init(gl.detach()); | |
194 } | |
195 | |
196 SkCommandBufferGLContext::~SkCommandBufferGLContext() { | |
197 this->teardown(); | |
198 this->destroyGLContext(); | |
199 } | |
200 | |
201 void SkCommandBufferGLContext::destroyGLContext() { | |
202 if (!gfFunctionsLoadedSuccessfully) { | |
203 return; | |
204 } | |
205 if (fDisplay) { | |
206 gfMakeCurrent(fDisplay, 0, 0, 0); | |
207 | |
208 if (fContext) { | |
209 gfDestroyContext(fDisplay, fContext); | |
210 fContext = EGL_NO_CONTEXT; | |
211 } | |
212 | |
213 if (fSurface) { | |
214 gfDestroySurface(fDisplay, fSurface); | |
215 fSurface = EGL_NO_SURFACE; | |
216 } | |
217 | |
218 gfTerminate(fDisplay); | |
219 fDisplay = EGL_NO_DISPLAY; | |
220 } | |
221 } | |
222 | |
223 void SkCommandBufferGLContext::onPlatformMakeCurrent() const { | |
224 if (!gfFunctionsLoadedSuccessfully) { | |
225 return; | |
226 } | |
227 if (!gfMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | |
228 SkDebugf("Could not set the context.\n"); | |
229 } | |
230 } | |
231 | |
232 void SkCommandBufferGLContext::onPlatformSwapBuffers() const { | |
233 if (!gfFunctionsLoadedSuccessfully) { | |
234 return; | |
235 } | |
236 if (!gfSwapBuffers(fDisplay, fSurface)) { | |
237 SkDebugf("Could not complete gfSwapBuffers.\n"); | |
238 } | |
239 } | |
240 | |
241 GrGLFuncPtr SkCommandBufferGLContext::onPlatformGetProcAddress(const char* name) const { | |
242 if (!gfFunctionsLoadedSuccessfully) { | |
243 return nullptr; | |
244 } | |
245 return gfGetProcAddress(name); | |
246 } | |
247 | |
248 void SkCommandBufferGLContext::presentCommandBuffer() { | |
249 SkAutoTUnref<const GrGLInterface> intf(GrGLCreateCommandBufferInterface()); | |
bsalomon
2015/08/27 13:47:13
I think you can just use this->gl() to get a GrGLI
hendrikw
2015/08/27 14:41:58
Done.
| |
250 if (intf) { | |
251 intf->fFunctions.fFlush(); | |
252 } | |
253 | |
254 onPlatformSwapBuffers(); | |
bsalomon
2015/08/27 13:47:13
this->
hendrikw
2015/08/27 14:41:58
Done.
| |
255 } | |
256 | |
257 bool SkCommandBufferGLContext::makeCurrent() { | |
258 return gfMakeCurrent(fDisplay, fSurface, fSurface, fContext) != EGL_FALSE; | |
259 } | |
260 | |
261 int SkCommandBufferGLContext::getStencilBits() { | |
262 EGLint result = 0; | |
263 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); | |
264 gfGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &result); | |
265 return result; | |
266 } | |
267 | |
268 int SkCommandBufferGLContext::getSampleCount() { | |
269 EGLint result = 0; | |
270 EGLConfig surfaceConfig = static_cast<EGLConfig>(fConfig); | |
271 gfGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &result); | |
272 return result; | |
273 } | |
OLD | NEW |