1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "skia/include/gpu/GrContext.h"
7 #include "skia/include/gpu/gl/GrGLInterface.h"
8 #include "mozilla/gfx/2D.h"
9 #include "mozilla/ThreadLocal.h"
10 #include "mozilla/DebugOnly.h"
11
12 /* SkPostConfig.h includes windows.h, which includes windef.h
13 * which redefines min/max. We don't want that. */
14 #ifdef _WIN32
15 #undef min
16 #undef max
17 #endif
18
19 #include "GLContext.h"
20 #include "SkiaGLGlue.h"
21
22 using mozilla::gl::GLContext;
23 using mozilla::gl::GLFeature;
24 using mozilla::gl::SkiaGLGlue;
25
26 template <typename R, typename... A>
WrapGL(RefPtr<GLContext> aContext,R (GLContext::* aFunc)(A...))27 static inline GrGLFunction<R (*)(A...)> WrapGL(RefPtr<GLContext> aContext,
28 R (GLContext::*aFunc)(A...)) {
29 return [aContext, aFunc](A... args) -> R {
30 aContext->MakeCurrent();
31 return (aContext->*aFunc)(args...);
32 };
33 }
34
35 template <typename R, typename... A>
WrapGL(RefPtr<GLContext> aContext,R (* aFunc)(GLContext *,A...))36 static inline GrGLFunction<R (*)(A...)> WrapGL(RefPtr<GLContext> aContext,
37 R (*aFunc)(GLContext*, A...)) {
38 return [aContext, aFunc](A... args) -> R {
39 aContext->MakeCurrent();
40 return (*aFunc)(aContext, args...);
41 };
42 }
43
44 // Core GL functions required by Ganesh
45
glGetString_mozilla(GLContext * aContext,GrGLenum aName)46 static const GLubyte* glGetString_mozilla(GLContext* aContext, GrGLenum aName) {
47 // GLContext only exposes a OpenGL 2.0 style API, so we have to intercept a
48 // bunch of checks that Ganesh makes to determine which capabilities are
49 // present on the GL implementation and change them to match what GLContext
50 // actually exposes.
51
52 if (aName == LOCAL_GL_VERSION) {
53 if (aContext->IsGLES()) {
54 return reinterpret_cast<const GLubyte*>("OpenGL ES 2.0");
55 }
56 return reinterpret_cast<const GLubyte*>("2.0");
57 } else if (aName == LOCAL_GL_EXTENSIONS) {
58 // Only expose the bare minimum extensions we want to support to ensure a
59 // functional Ganesh as GLContext only exposes certain extensions
60 static bool extensionsStringBuilt = false;
61 static char extensionsString[1024];
62
63 if (!extensionsStringBuilt) {
64 extensionsString[0] = '\0';
65
66 if (aContext->IsGLES()) {
67 // OES is only applicable to GLES2
68 if (aContext->IsExtensionSupported(
69 GLContext::OES_packed_depth_stencil)) {
70 strcat(extensionsString, "GL_OES_packed_depth_stencil ");
71 }
72
73 if (aContext->IsExtensionSupported(GLContext::OES_rgb8_rgba8)) {
74 strcat(extensionsString, "GL_OES_rgb8_rgba8 ");
75 }
76
77 if (aContext->IsExtensionSupported(GLContext::OES_texture_npot)) {
78 strcat(extensionsString, "GL_OES_texture_npot ");
79 }
80
81 if (aContext->IsExtensionSupported(
82 GLContext::OES_vertex_array_object)) {
83 strcat(extensionsString, "GL_OES_vertex_array_object ");
84 }
85
86 if (aContext->IsSupported(GLFeature::standard_derivatives)) {
87 strcat(extensionsString, "GL_OES_standard_derivatives ");
88 }
89 } else {
90 if (aContext->IsSupported(GLFeature::framebuffer_object)) {
91 strcat(extensionsString, "GL_ARB_framebuffer_object ");
92 } else if (aContext->IsExtensionSupported(
93 GLContext::EXT_framebuffer_object)) {
94 strcat(extensionsString, "GL_EXT_framebuffer_object ");
95 }
96
97 if (aContext->IsSupported(GLFeature::texture_rg)) {
98 strcat(extensionsString, "GL_ARB_texture_rg ");
99 }
100 }
101
102 if (aContext->IsExtensionSupported(
103 GLContext::EXT_texture_format_BGRA8888)) {
104 strcat(extensionsString, "GL_EXT_texture_format_BGRA8888 ");
105 }
106
107 if (aContext->IsExtensionSupported(GLContext::EXT_packed_depth_stencil)) {
108 strcat(extensionsString, "GL_EXT_packed_depth_stencil ");
109 }
110
111 if (aContext->IsExtensionSupported(GLContext::EXT_bgra)) {
112 strcat(extensionsString, "GL_EXT_bgra ");
113 }
114
115 if (aContext->IsExtensionSupported(GLContext::EXT_read_format_bgra)) {
116 strcat(extensionsString, "GL_EXT_read_format_bgra ");
117 }
118
119 extensionsStringBuilt = true;
120 #ifdef DEBUG
121 printf_stderr("Exported SkiaGL extensions: %s\n", extensionsString);
122 #endif
123 }
124
125 return reinterpret_cast<const GLubyte*>(extensionsString);
126
127 } else if (aName == LOCAL_GL_SHADING_LANGUAGE_VERSION) {
128 if (aContext->IsGLES()) {
129 return reinterpret_cast<const GLubyte*>("OpenGL ES GLSL ES 1.0");
130 }
131 return reinterpret_cast<const GLubyte*>("1.10");
132 }
133
134 return aContext->fGetString(aName);
135 }
136
CreateGrGLInterfaceFromGLContext(GLContext * context)137 static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context) {
138 auto* i = new GrGLInterface();
139
140 context->MakeCurrent();
141
142 // We support both desktop GL and GLES2
143 if (context->IsGLES()) {
144 i->fStandard = kGLES_GrGLStandard;
145 } else {
146 i->fStandard = kGL_GrGLStandard;
147 }
148
149 GrGLFunction<GrGLGetStringProc> getString =
150 WrapGL(context, &glGetString_mozilla);
151 GrGLFunction<GrGLGetIntegervProc> getIntegerv =
152 WrapGL(context, &GLContext::fGetIntegerv);
153
154 GrGLExtensions extensions;
155 if (!extensions.init(i->fStandard, getString, nullptr, getIntegerv)) {
156 delete i;
157 return nullptr;
158 }
159
160 i->fExtensions.swap(&extensions);
161
162 // Core GL functions required by Ganesh
163 i->fFunctions.fActiveTexture = WrapGL(context, &GLContext::fActiveTexture);
164 i->fFunctions.fAttachShader = WrapGL(context, &GLContext::fAttachShader);
165 i->fFunctions.fBindAttribLocation =
166 WrapGL(context, &GLContext::fBindAttribLocation);
167 i->fFunctions.fBindBuffer = WrapGL(context, &GLContext::fBindBuffer);
168 i->fFunctions.fBindFramebuffer =
169 WrapGL(context, &GLContext::fBindFramebuffer);
170 i->fFunctions.fBindRenderbuffer =
171 WrapGL(context, &GLContext::fBindRenderbuffer);
172 i->fFunctions.fBindTexture = WrapGL(context, &GLContext::fBindTexture);
173 i->fFunctions.fBlendFunc = WrapGL(context, &GLContext::fBlendFunc);
174 i->fFunctions.fBlendColor = WrapGL(context, &GLContext::fBlendColor);
175 i->fFunctions.fBlendEquation = WrapGL(context, &GLContext::fBlendEquation);
176 i->fFunctions.fBufferData = WrapGL(context, &GLContext::fBufferData);
177 i->fFunctions.fBufferSubData = WrapGL(context, &GLContext::fBufferSubData);
178 i->fFunctions.fCheckFramebufferStatus =
179 WrapGL(context, &GLContext::fCheckFramebufferStatus);
180 i->fFunctions.fClear = WrapGL(context, &GLContext::fClear);
181 i->fFunctions.fClearColor = WrapGL(context, &GLContext::fClearColor);
182 i->fFunctions.fClearStencil = WrapGL(context, &GLContext::fClearStencil);
183 i->fFunctions.fColorMask = WrapGL(context, &GLContext::fColorMask);
184 i->fFunctions.fCompileShader = WrapGL(context, &GLContext::fCompileShader);
185 i->fFunctions.fCompressedTexImage2D =
186 WrapGL(context, &GLContext::fCompressedTexImage2D);
187 i->fFunctions.fCompressedTexSubImage2D =
188 WrapGL(context, &GLContext::fCompressedTexSubImage2D);
189 i->fFunctions.fCopyTexSubImage2D =
190 WrapGL(context, &GLContext::fCopyTexSubImage2D);
191 i->fFunctions.fCreateProgram = WrapGL(context, &GLContext::fCreateProgram);
192 i->fFunctions.fCreateShader = WrapGL(context, &GLContext::fCreateShader);
193 i->fFunctions.fCullFace = WrapGL(context, &GLContext::fCullFace);
194 i->fFunctions.fDeleteBuffers = WrapGL(context, &GLContext::fDeleteBuffers);
195 i->fFunctions.fDeleteFramebuffers =
196 WrapGL(context, &GLContext::fDeleteFramebuffers);
197 i->fFunctions.fDeleteProgram = WrapGL(context, &GLContext::fDeleteProgram);
198 i->fFunctions.fDeleteRenderbuffers =
199 WrapGL(context, &GLContext::fDeleteRenderbuffers);
200 i->fFunctions.fDeleteShader = WrapGL(context, &GLContext::fDeleteShader);
201 i->fFunctions.fDeleteTextures = WrapGL(context, &GLContext::fDeleteTextures);
202 i->fFunctions.fDepthMask = WrapGL(context, &GLContext::fDepthMask);
203 i->fFunctions.fDisable = WrapGL(context, &GLContext::fDisable);
204 i->fFunctions.fDisableVertexAttribArray =
205 WrapGL(context, &GLContext::fDisableVertexAttribArray);
206 i->fFunctions.fDrawArrays = WrapGL(context, &GLContext::fDrawArrays);
207 i->fFunctions.fDrawElements = WrapGL(context, &GLContext::fDrawElements);
208 i->fFunctions.fDrawRangeElements =
209 WrapGL(context, &GLContext::fDrawRangeElements);
210 i->fFunctions.fEnable = WrapGL(context, &GLContext::fEnable);
211 i->fFunctions.fEnableVertexAttribArray =
212 WrapGL(context, &GLContext::fEnableVertexAttribArray);
213 i->fFunctions.fFinish = WrapGL(context, &GLContext::fFinish);
214 i->fFunctions.fFlush = WrapGL(context, &GLContext::fFlush);
215 i->fFunctions.fFramebufferRenderbuffer =
216 WrapGL(context, &GLContext::fFramebufferRenderbuffer);
217 i->fFunctions.fFramebufferTexture2D =
218 WrapGL(context, &GLContext::fFramebufferTexture2D);
219 i->fFunctions.fFrontFace = WrapGL(context, &GLContext::fFrontFace);
220 i->fFunctions.fGenBuffers = WrapGL(context, &GLContext::fGenBuffers);
221 i->fFunctions.fGenFramebuffers =
222 WrapGL(context, &GLContext::fGenFramebuffers);
223 i->fFunctions.fGenRenderbuffers =
224 WrapGL(context, &GLContext::fGenRenderbuffers);
225 i->fFunctions.fGetFramebufferAttachmentParameteriv =
226 WrapGL(context, &GLContext::fGetFramebufferAttachmentParameteriv);
227 i->fFunctions.fGenTextures = WrapGL(context, &GLContext::fGenTextures);
228 i->fFunctions.fGenerateMipmap = WrapGL(context, &GLContext::fGenerateMipmap);
229 i->fFunctions.fGetBufferParameteriv =
230 WrapGL(context, &GLContext::fGetBufferParameteriv);
231 i->fFunctions.fGetError = WrapGL(context, &GLContext::fGetError);
232 i->fFunctions.fGetIntegerv = getIntegerv;
233 i->fFunctions.fGetProgramInfoLog =
234 WrapGL(context, &GLContext::fGetProgramInfoLog);
235 i->fFunctions.fGetProgramiv = WrapGL(context, &GLContext::fGetProgramiv);
236 i->fFunctions.fGetRenderbufferParameteriv =
237 WrapGL(context, &GLContext::fGetRenderbufferParameteriv);
238 i->fFunctions.fGetShaderInfoLog =
239 WrapGL(context, &GLContext::fGetShaderInfoLog);
240 i->fFunctions.fGetShaderiv = WrapGL(context, &GLContext::fGetShaderiv);
241 i->fFunctions.fGetShaderPrecisionFormat =
242 WrapGL(context, &GLContext::fGetShaderPrecisionFormat);
243 i->fFunctions.fGetString = getString;
244 i->fFunctions.fGetUniformLocation =
245 WrapGL(context, &GLContext::fGetUniformLocation);
246 i->fFunctions.fIsTexture = WrapGL(context, &GLContext::fIsTexture);
247 i->fFunctions.fLineWidth = WrapGL(context, &GLContext::fLineWidth);
248 i->fFunctions.fLinkProgram = WrapGL(context, &GLContext::fLinkProgram);
249 i->fFunctions.fPixelStorei = WrapGL(context, &GLContext::fPixelStorei);
250 i->fFunctions.fPolygonMode = WrapGL(context, &GLContext::fPolygonMode);
251 i->fFunctions.fReadPixels = WrapGL(context, &GLContext::fReadPixels);
252 i->fFunctions.fRenderbufferStorage =
253 WrapGL(context, &GLContext::fRenderbufferStorage);
254 i->fFunctions.fScissor = WrapGL(context, &GLContext::fScissor);
255 i->fFunctions.fShaderSource = WrapGL(context, &GLContext::fShaderSource);
256 i->fFunctions.fStencilFunc = WrapGL(context, &GLContext::fStencilFunc);
257 i->fFunctions.fStencilFuncSeparate =
258 WrapGL(context, &GLContext::fStencilFuncSeparate);
259 i->fFunctions.fStencilMask = WrapGL(context, &GLContext::fStencilMask);
260 i->fFunctions.fStencilMaskSeparate =
261 WrapGL(context, &GLContext::fStencilMaskSeparate);
262 i->fFunctions.fStencilOp = WrapGL(context, &GLContext::fStencilOp);
263 i->fFunctions.fStencilOpSeparate =
264 WrapGL(context, &GLContext::fStencilOpSeparate);
265 i->fFunctions.fTexImage2D = WrapGL(context, &GLContext::fTexImage2D);
266 i->fFunctions.fTexParameteri = WrapGL(context, &GLContext::fTexParameteri);
267 i->fFunctions.fTexParameteriv = WrapGL(context, &GLContext::fTexParameteriv);
268 i->fFunctions.fTexSubImage2D = WrapGL(context, &GLContext::fTexSubImage2D);
269 i->fFunctions.fUniform1f = WrapGL(context, &GLContext::fUniform1f);
270 i->fFunctions.fUniform1i = WrapGL(context, &GLContext::fUniform1i);
271 i->fFunctions.fUniform1fv = WrapGL(context, &GLContext::fUniform1fv);
272 i->fFunctions.fUniform1iv = WrapGL(context, &GLContext::fUniform1iv);
273 i->fFunctions.fUniform2f = WrapGL(context, &GLContext::fUniform2f);
274 i->fFunctions.fUniform2i = WrapGL(context, &GLContext::fUniform2i);
275 i->fFunctions.fUniform2fv = WrapGL(context, &GLContext::fUniform2fv);
276 i->fFunctions.fUniform2iv = WrapGL(context, &GLContext::fUniform2iv);
277 i->fFunctions.fUniform3f = WrapGL(context, &GLContext::fUniform3f);
278 i->fFunctions.fUniform3i = WrapGL(context, &GLContext::fUniform3i);
279 i->fFunctions.fUniform3fv = WrapGL(context, &GLContext::fUniform3fv);
280 i->fFunctions.fUniform3iv = WrapGL(context, &GLContext::fUniform3iv);
281 i->fFunctions.fUniform4f = WrapGL(context, &GLContext::fUniform4f);
282 i->fFunctions.fUniform4i = WrapGL(context, &GLContext::fUniform4i);
283 i->fFunctions.fUniform4fv = WrapGL(context, &GLContext::fUniform4fv);
284 i->fFunctions.fUniform4iv = WrapGL(context, &GLContext::fUniform4iv);
285 i->fFunctions.fUniformMatrix2fv =
286 WrapGL(context, &GLContext::fUniformMatrix2fv);
287 i->fFunctions.fUniformMatrix3fv =
288 WrapGL(context, &GLContext::fUniformMatrix3fv);
289 i->fFunctions.fUniformMatrix4fv =
290 WrapGL(context, &GLContext::fUniformMatrix4fv);
291 i->fFunctions.fUseProgram = WrapGL(context, &GLContext::fUseProgram);
292 i->fFunctions.fVertexAttrib1f = WrapGL(context, &GLContext::fVertexAttrib1f);
293 i->fFunctions.fVertexAttrib2fv =
294 WrapGL(context, &GLContext::fVertexAttrib2fv);
295 i->fFunctions.fVertexAttrib3fv =
296 WrapGL(context, &GLContext::fVertexAttrib3fv);
297 i->fFunctions.fVertexAttrib4fv =
298 WrapGL(context, &GLContext::fVertexAttrib4fv);
299 i->fFunctions.fVertexAttribPointer =
300 WrapGL(context, &GLContext::fVertexAttribPointer);
301 i->fFunctions.fViewport = WrapGL(context, &GLContext::fViewport);
302
303 // Required for either desktop OpenGL 2.0 or OpenGL ES 2.0
304 i->fFunctions.fStencilFuncSeparate =
305 WrapGL(context, &GLContext::fStencilFuncSeparate);
306 i->fFunctions.fStencilMaskSeparate =
307 WrapGL(context, &GLContext::fStencilMaskSeparate);
308 i->fFunctions.fStencilOpSeparate =
309 WrapGL(context, &GLContext::fStencilOpSeparate);
310
311 // GLContext supports glMapBuffer
312 i->fFunctions.fMapBuffer = WrapGL(context, &GLContext::fMapBuffer);
313 i->fFunctions.fUnmapBuffer = WrapGL(context, &GLContext::fUnmapBuffer);
314
315 // GLContext supports glRenderbufferStorageMultisample/glBlitFramebuffer
316 i->fFunctions.fRenderbufferStorageMultisample =
317 WrapGL(context, &GLContext::fRenderbufferStorageMultisample);
318 i->fFunctions.fBlitFramebuffer =
319 WrapGL(context, &GLContext::fBlitFramebuffer);
320
321 // GLContext supports glCompressedTexImage2D
322 i->fFunctions.fCompressedTexImage2D =
323 WrapGL(context, &GLContext::fCompressedTexImage2D);
324
325 // GL_OES_vertex_array_object
326 i->fFunctions.fBindVertexArray =
327 WrapGL(context, &GLContext::fBindVertexArray);
328 i->fFunctions.fDeleteVertexArrays =
329 WrapGL(context, &GLContext::fDeleteVertexArrays);
330 i->fFunctions.fGenVertexArrays =
331 WrapGL(context, &GLContext::fGenVertexArrays);
332
333 // Desktop GL
334 i->fFunctions.fGetTexLevelParameteriv =
335 WrapGL(context, &GLContext::fGetTexLevelParameteriv);
336 i->fFunctions.fDrawBuffer = WrapGL(context, &GLContext::fDrawBuffer);
337 i->fFunctions.fReadBuffer = WrapGL(context, &GLContext::fReadBuffer);
338
339 // Desktop OpenGL > 1.5
340 i->fFunctions.fGenQueries = WrapGL(context, &GLContext::fGenQueries);
341 i->fFunctions.fDeleteQueries = WrapGL(context, &GLContext::fDeleteQueries);
342 i->fFunctions.fBeginQuery = WrapGL(context, &GLContext::fBeginQuery);
343 i->fFunctions.fEndQuery = WrapGL(context, &GLContext::fEndQuery);
344 i->fFunctions.fGetQueryiv = WrapGL(context, &GLContext::fGetQueryiv);
345 i->fFunctions.fGetQueryObjectiv =
346 WrapGL(context, &GLContext::fGetQueryObjectiv);
347 i->fFunctions.fGetQueryObjectuiv =
348 WrapGL(context, &GLContext::fGetQueryObjectuiv);
349
350 // Desktop OpenGL > 2.0
351 i->fFunctions.fDrawBuffers = WrapGL(context, &GLContext::fDrawBuffers);
352
353 return i;
354 }
355
SkiaGLGlue(GLContext * context)356 SkiaGLGlue::SkiaGLGlue(GLContext* context) : mGLContext(context) {
357 mGrGLInterface.reset(CreateGrGLInterfaceFromGLContext(mGLContext));
358 mGrContext.reset(GrContext::Create(kOpenGL_GrBackend,
359 (GrBackendContext)mGrGLInterface.get()));
360 }
361
~SkiaGLGlue()362 SkiaGLGlue::~SkiaGLGlue() {
363 /*
364 * These members have inter-dependencies, but do not keep each other alive, so
365 * destruction order is very important here: mGrContext uses mGrGLInterface,
366 * and through it, uses mGLContext
367 */
368 mGrContext = nullptr;
369 if (mGrGLInterface) {
370 // Ensure that no references to the GLContext remain, even if the GrContext
371 // still lives.
372 mGrGLInterface->fFunctions = GrGLInterface::Functions();
373 mGrGLInterface = nullptr;
374 }
375 mGLContext = nullptr;
376 }
377