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