1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 
9 #include "gl/GrGLAssembleInterface.h"
10 #include "GrGLUtil.h"
11 
12 #define GET_PROC(F) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F)
13 #define GET_PROC_SUFFIX(F, S) functions->f##F = (GrGL##F##Fn*)get(ctx, "gl" #F #S)
14 #define GET_PROC_LOCAL(F) GrGL##F##Fn* F = (GrGL##F##Fn*)get(ctx, "gl" #F)
15 
16 #define GET_EGL_PROC_SUFFIX(F, S) functions->fEGL##F = (GrEGL##F##Fn*)get(ctx, "egl" #F #S)
17 
GrGLMakeAssembledInterface(void * ctx,GrGLGetProc get)18 sk_sp<const GrGLInterface> GrGLMakeAssembledInterface(void *ctx, GrGLGetProc get) {
19     GET_PROC_LOCAL(GetString);
20     if (nullptr == GetString) {
21         return nullptr;
22     }
23 
24     const char* verStr = reinterpret_cast<const char*>(GetString(GR_GL_VERSION));
25     if (nullptr == verStr) {
26         return nullptr;
27     }
28 
29     GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
30 
31     if (kGLES_GrGLStandard == standard) {
32         return GrGLMakeAssembledGLESInterface(ctx, get);
33     } else if (kGL_GrGLStandard == standard) {
34         return GrGLMakeAssembledGLInterface(ctx, get);
35     }
36     return nullptr;
37 }
38 
get_egl_query_and_display(GrEGLQueryStringFn ** queryString,GrEGLDisplay * display,void * ctx,GrGLGetProc get)39 static void get_egl_query_and_display(GrEGLQueryStringFn** queryString, GrEGLDisplay* display,
40                                       void* ctx, GrGLGetProc get) {
41     *queryString = (GrEGLQueryStringFn*)get(ctx, "eglQueryString");
42     *display = GR_EGL_NO_DISPLAY;
43     if (*queryString) {
44         GrEGLGetCurrentDisplayFn* getCurrentDisplay =
45                 (GrEGLGetCurrentDisplayFn*)get(ctx, "eglGetCurrentDisplay");
46         if (getCurrentDisplay) {
47             *display = getCurrentDisplay();
48         } else {
49             *queryString = nullptr;
50         }
51     }
52 }
53 
GrGLMakeAssembledGLInterface(void * ctx,GrGLGetProc get)54 sk_sp<const GrGLInterface> GrGLMakeAssembledGLInterface(void *ctx, GrGLGetProc get) {
55     GET_PROC_LOCAL(GetString);
56     GET_PROC_LOCAL(GetStringi);
57     GET_PROC_LOCAL(GetIntegerv);
58 
59     // GetStringi may be nullptr depending on the GL version.
60     if (nullptr == GetString || nullptr == GetIntegerv) {
61         return nullptr;
62     }
63 
64     const char* versionString = (const char*) GetString(GR_GL_VERSION);
65     GrGLVersion glVer = GrGLGetVersionFromString(versionString);
66 
67     if (glVer < GR_GL_VER(2,0) || GR_GL_INVALID_VER == glVer) {
68         // This is our minimum for non-ES GL.
69         return nullptr;
70     }
71 
72     GrEGLQueryStringFn* queryString;
73     GrEGLDisplay display;
74     get_egl_query_and_display(&queryString, &display, ctx, get);
75     GrGLExtensions extensions;
76     if (!extensions.init(kGL_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
77                          display)) {
78         return nullptr;
79     }
80 
81     sk_sp<GrGLInterface> interface(new GrGLInterface());
82     GrGLInterface::Functions* functions = &interface->fFunctions;
83 
84     GET_PROC(ActiveTexture);
85     GET_PROC(AttachShader);
86     GET_PROC(BindAttribLocation);
87     GET_PROC(BindBuffer);
88     if (glVer >= GR_GL_VER(3,0)) {
89         GET_PROC(BindFragDataLocation);
90     }
91     GET_PROC(BeginQuery);
92     GET_PROC(BindTexture);
93 
94     if (extensions.has("GL_KHR_blend_equation_advanced")) {
95         GET_PROC_SUFFIX(BlendBarrier, KHR);
96     } else if (extensions.has("GL_NV_blend_equation_advanced")) {
97         GET_PROC_SUFFIX(BlendBarrier, NV);
98     }
99 
100     GET_PROC(BlendColor);
101     GET_PROC(BlendEquation);
102     GET_PROC(BlendFunc);
103     GET_PROC(BufferData);
104     GET_PROC(BufferSubData);
105     GET_PROC(Clear);
106     GET_PROC(ClearColor);
107     GET_PROC(ClearStencil);
108     if (glVer >= GR_GL_VER(4,4) || extensions.has("GL_ARB_clear_texture")) {
109         GET_PROC(ClearTexImage);
110         GET_PROC(ClearTexSubImage);
111     }
112     GET_PROC(ColorMask);
113     GET_PROC(CompileShader);
114     GET_PROC(CompressedTexImage2D);
115     GET_PROC(CompressedTexSubImage2D);
116     GET_PROC(CopyTexSubImage2D);
117     GET_PROC(CreateProgram);
118     GET_PROC(CreateShader);
119     GET_PROC(CullFace);
120     GET_PROC(DeleteBuffers);
121     GET_PROC(DeleteProgram);
122     GET_PROC(DeleteQueries);
123     GET_PROC(DeleteShader);
124     GET_PROC(DeleteTextures);
125     GET_PROC(DepthMask);
126     GET_PROC(Disable);
127     GET_PROC(DisableVertexAttribArray);
128     GET_PROC(DrawArrays);
129     GET_PROC(DrawBuffer);
130     GET_PROC(DrawBuffers);
131     GET_PROC(DrawElements);
132 
133     if (glVer >= GR_GL_VER(3,1) || extensions.has("GL_ARB_draw_instanced") ||
134         extensions.has("GL_EXT_draw_instanced")) {
135         GET_PROC(DrawArraysInstanced);
136         GET_PROC(DrawElementsInstanced);
137     }
138 
139     if (glVer >= GR_GL_VER(4,0) || extensions.has("GL_ARB_draw_indirect")) {
140         GET_PROC(DrawArraysIndirect);
141         GET_PROC(DrawElementsIndirect);
142     }
143     GET_PROC(DrawRangeElements);
144     GET_PROC(Enable);
145     GET_PROC(EnableVertexAttribArray);
146     GET_PROC(EndQuery);
147     GET_PROC(Finish);
148     GET_PROC(Flush);
149     GET_PROC(FrontFace);
150     GET_PROC(GenBuffers);
151     GET_PROC(GetBufferParameteriv);
152     GET_PROC(GetError);
153     GET_PROC(GetIntegerv);
154     if (glVer >= GR_GL_VER(3,2) || extensions.has("GL_ARB_texture_multisample")) {
155         GET_PROC(GetMultisamplefv);
156     }
157     GET_PROC(GetQueryObjectiv);
158     GET_PROC(GetQueryObjectuiv);
159     if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
160         GET_PROC(GetQueryObjecti64v);
161         GET_PROC(GetQueryObjectui64v);
162         GET_PROC(QueryCounter);
163     } else if (extensions.has("GL_EXT_timer_query")) {
164         GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
165         GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
166     }
167     GET_PROC(GetQueryiv);
168     GET_PROC(GetProgramInfoLog);
169     GET_PROC(GetProgramiv);
170     GET_PROC(GetShaderInfoLog);
171     GET_PROC(GetShaderiv);
172     GET_PROC(GetString);
173     GET_PROC(GetStringi);
174     GET_PROC(GetShaderPrecisionFormat);
175     GET_PROC(GetTexLevelParameteriv);
176     GET_PROC(GenQueries);
177     GET_PROC(GenTextures);
178     GET_PROC(GetUniformLocation);
179     GET_PROC(IsTexture);
180     GET_PROC(LineWidth);
181     GET_PROC(LinkProgram);
182     GET_PROC(MapBuffer);
183 
184     if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_ARB_multi_draw_indirect")) {
185         GET_PROC(MultiDrawArraysIndirect);
186         GET_PROC(MultiDrawElementsIndirect);
187     }
188 
189     GET_PROC(PixelStorei);
190     GET_PROC(PolygonMode);
191     if (extensions.has("GL_EXT_raster_multisample")) {
192         GET_PROC_SUFFIX(RasterSamples, EXT);
193     }
194     GET_PROC(ReadBuffer);
195     GET_PROC(ReadPixels);
196     GET_PROC(Scissor);
197     GET_PROC(ShaderSource);
198     GET_PROC(StencilFunc);
199     GET_PROC(StencilFuncSeparate);
200     GET_PROC(StencilMask);
201     GET_PROC(StencilMaskSeparate);
202     GET_PROC(StencilOp);
203     GET_PROC(StencilOpSeparate);
204     if (glVer >= GR_GL_VER(3,1)) {
205         GET_PROC(TexBuffer);
206     }
207     if (glVer >= GR_GL_VER(4,3)) {
208         GET_PROC(TexBufferRange);
209     }
210     GET_PROC(TexImage2D);
211     GET_PROC(TexParameterf);
212     GET_PROC(TexParameterfv);
213     GET_PROC(TexParameteri);
214     GET_PROC(TexParameteriv);
215     if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
216         GET_PROC(TexStorage2D);
217     } else if (extensions.has("GL_EXT_texture_storage")) {
218         GET_PROC_SUFFIX(TexStorage2D, EXT);
219     }
220     GET_PROC(TexSubImage2D);
221     if (glVer >= GR_GL_VER(4,5) || extensions.has("GL_ARB_texture_barrier")) {
222         GET_PROC(TextureBarrier);
223     } else if (extensions.has("GL_NV_texture_barrier")) {
224         GET_PROC_SUFFIX(TextureBarrier, NV);
225     }
226     GET_PROC(Uniform1f);
227     GET_PROC(Uniform1i);
228     GET_PROC(Uniform1fv);
229     GET_PROC(Uniform1iv);
230     GET_PROC(Uniform2f);
231     GET_PROC(Uniform2i);
232     GET_PROC(Uniform2fv);
233     GET_PROC(Uniform2iv);
234     GET_PROC(Uniform3f);
235     GET_PROC(Uniform3i);
236     GET_PROC(Uniform3fv);
237     GET_PROC(Uniform3iv);
238     GET_PROC(Uniform4f);
239     GET_PROC(Uniform4i);
240     GET_PROC(Uniform4fv);
241     GET_PROC(Uniform4iv);
242     GET_PROC(UniformMatrix2fv);
243     GET_PROC(UniformMatrix3fv);
244     GET_PROC(UniformMatrix4fv);
245     GET_PROC(UnmapBuffer);
246     GET_PROC(UseProgram);
247     GET_PROC(VertexAttrib1f);
248     GET_PROC(VertexAttrib2fv);
249     GET_PROC(VertexAttrib3fv);
250     GET_PROC(VertexAttrib4fv);
251 
252     if (glVer >= GR_GL_VER(3,2) || extensions.has("GL_ARB_instanced_arrays")) {
253         GET_PROC(VertexAttribDivisor);
254     }
255 
256     if (glVer >= GR_GL_VER(3,0)) {
257         GET_PROC(VertexAttribIPointer);
258     }
259 
260     GET_PROC(VertexAttribPointer);
261     GET_PROC(Viewport);
262     GET_PROC(BindFragDataLocationIndexed);
263 
264     if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) {
265         // no ARB suffix for GL_ARB_vertex_array_object
266         GET_PROC(BindVertexArray);
267         GET_PROC(GenVertexArrays);
268         GET_PROC(DeleteVertexArrays);
269     } else if (extensions.has("GL_APPLE_vertex_array_object")) {
270         GET_PROC_SUFFIX(BindVertexArray, APPLE);
271         GET_PROC_SUFFIX(GenVertexArrays, APPLE);
272         GET_PROC_SUFFIX(DeleteVertexArrays, APPLE);
273     }
274 
275     if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_map_buffer_range")) {
276         GET_PROC(MapBufferRange);
277         GET_PROC(FlushMappedBufferRange);
278     }
279 
280     // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
281     // GL_ARB_framebuffer_object doesn't use ARB suffix.)
282     if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
283         GET_PROC(GenerateMipmap);
284         GET_PROC(GenFramebuffers);
285         GET_PROC(GetFramebufferAttachmentParameteriv);
286         GET_PROC(GetRenderbufferParameteriv);
287         GET_PROC(BindFramebuffer);
288         GET_PROC(FramebufferTexture2D);
289         GET_PROC(CheckFramebufferStatus);
290         GET_PROC(DeleteFramebuffers);
291         GET_PROC(RenderbufferStorage);
292         GET_PROC(GenRenderbuffers);
293         GET_PROC(DeleteRenderbuffers);
294         GET_PROC(FramebufferRenderbuffer);
295         GET_PROC(BindRenderbuffer);
296         GET_PROC(RenderbufferStorageMultisample);
297         GET_PROC(BlitFramebuffer);
298     } else if (extensions.has("GL_EXT_framebuffer_object")) {
299         GET_PROC_SUFFIX(GenerateMipmap, EXT);
300         GET_PROC_SUFFIX(GenFramebuffers, EXT);
301         GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
302         GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
303         GET_PROC_SUFFIX(BindFramebuffer, EXT);
304         GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
305         GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
306         GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
307         GET_PROC_SUFFIX(RenderbufferStorage, EXT);
308         GET_PROC_SUFFIX(GenRenderbuffers, EXT);
309         GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
310         GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
311         GET_PROC_SUFFIX(BindRenderbuffer, EXT);
312         if (extensions.has("GL_EXT_framebuffer_multisample")) {
313             GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
314         }
315         if (extensions.has("GL_EXT_framebuffer_blit")) {
316             GET_PROC_SUFFIX(BlitFramebuffer, EXT);
317         }
318     } else {
319         // we must have FBOs
320         return nullptr;
321     }
322 
323     if (extensions.has("GL_NV_path_rendering")) {
324         GET_PROC_SUFFIX(MatrixLoadf, EXT);
325         GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
326         GET_PROC_SUFFIX(PathCommands, NV);
327         GET_PROC_SUFFIX(PathParameteri, NV);
328         GET_PROC_SUFFIX(PathParameterf, NV);
329         GET_PROC_SUFFIX(GenPaths, NV);
330         GET_PROC_SUFFIX(DeletePaths, NV);
331         GET_PROC_SUFFIX(IsPath, NV);
332         GET_PROC_SUFFIX(PathStencilFunc, NV);
333         GET_PROC_SUFFIX(StencilFillPath, NV);
334         GET_PROC_SUFFIX(StencilStrokePath, NV);
335         GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
336         GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
337         GET_PROC_SUFFIX(CoverFillPath, NV);
338         GET_PROC_SUFFIX(CoverStrokePath, NV);
339         GET_PROC_SUFFIX(CoverFillPathInstanced, NV);
340         GET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
341         GET_PROC_SUFFIX(StencilThenCoverFillPath, NV);
342         GET_PROC_SUFFIX(StencilThenCoverStrokePath, NV);
343         GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, NV);
344         GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, NV);
345         GET_PROC_SUFFIX(ProgramPathFragmentInputGen, NV);
346     }
347 
348     if (extensions.has("GL_NV_framebuffer_mixed_samples")) {
349         GET_PROC_SUFFIX(CoverageModulation, NV);
350     }
351 
352     if (extensions.has("GL_EXT_debug_marker")) {
353         GET_PROC_SUFFIX(InsertEventMarker, EXT);
354         GET_PROC_SUFFIX(PushGroupMarker, EXT);
355         GET_PROC_SUFFIX(PopGroupMarker, EXT);
356     }
357 
358     if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_ARB_invalidate_subdata")) {
359         GET_PROC(InvalidateBufferData);
360         GET_PROC(InvalidateBufferSubData);
361         GET_PROC(InvalidateFramebuffer);
362         GET_PROC(InvalidateSubFramebuffer);
363         GET_PROC(InvalidateTexImage);
364         GET_PROC(InvalidateTexSubImage);
365     }
366 
367     if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_ARB_program_interface_query")) {
368         GET_PROC(GetProgramResourceLocation);
369     }
370 
371     if (glVer >= GR_GL_VER(4,3) || extensions.has("GL_KHR_debug")) {
372         // KHR_debug defines these methods to have no suffix in an OpenGL (not ES) context.
373         GET_PROC(DebugMessageControl);
374         GET_PROC(DebugMessageInsert);
375         GET_PROC(DebugMessageCallback);
376         GET_PROC(GetDebugMessageLog);
377         GET_PROC(PushDebugGroup);
378         GET_PROC(PopDebugGroup);
379         GET_PROC(ObjectLabel);
380     }
381 
382     if (extensions.has("GL_EXT_window_rectangles")) {
383         GET_PROC_SUFFIX(WindowRectangles, EXT);
384     }
385 
386     if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
387         GET_EGL_PROC_SUFFIX(CreateImage, KHR);
388         GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
389     }
390 
391     if (glVer >= GR_GL_VER(3, 2) || extensions.has("GL_ARB_sync")) {
392         GET_PROC(FenceSync);
393         GET_PROC(IsSync);
394         GET_PROC(ClientWaitSync);
395         GET_PROC(WaitSync);
396         GET_PROC(DeleteSync);
397     }
398 
399     if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_internalformat_query")) {
400         GET_PROC(GetInternalformativ);
401     }
402 
403     if (glVer >= GR_GL_VER(4, 1)) {
404         GET_PROC(GetProgramBinary);
405         GET_PROC(ProgramBinary);
406         GET_PROC(ProgramParameteri);
407     }
408 
409     if (glVer >= GR_GL_VER(3,2) || extensions.has("GL_ARB_sampler_objects")) {
410         GET_PROC(BindSampler);
411         GET_PROC(DeleteSamplers);
412         GET_PROC(GenSamplers);
413         GET_PROC(SamplerParameteri);
414         GET_PROC(SamplerParameteriv);
415     }
416 
417     interface->fStandard = kGL_GrGLStandard;
418     interface->fExtensions.swap(&extensions);
419 
420     return std::move(interface);
421 }
422 
GrGLMakeAssembledGLESInterface(void * ctx,GrGLGetProc get)423 sk_sp<const GrGLInterface> GrGLMakeAssembledGLESInterface(void *ctx, GrGLGetProc get) {
424     GET_PROC_LOCAL(GetString);
425     if (nullptr == GetString) {
426         return nullptr;
427     }
428 
429     const char* verStr = reinterpret_cast<const char*>(GetString(GR_GL_VERSION));
430     GrGLVersion version = GrGLGetVersionFromString(verStr);
431 
432     if (version < GR_GL_VER(2,0)) {
433         return nullptr;
434     }
435 
436     GET_PROC_LOCAL(GetIntegerv);
437     GET_PROC_LOCAL(GetStringi);
438     GrEGLQueryStringFn* queryString;
439     GrEGLDisplay display;
440     get_egl_query_and_display(&queryString, &display, ctx, get);
441     GrGLExtensions extensions;
442     if (!extensions.init(kGLES_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
443                          display)) {
444         return nullptr;
445     }
446 
447     sk_sp<GrGLInterface> interface(new GrGLInterface);
448     GrGLInterface::Functions* functions = &interface->fFunctions;
449 
450     GET_PROC(ActiveTexture);
451     GET_PROC(AttachShader);
452     GET_PROC(BindAttribLocation);
453     GET_PROC(BindBuffer);
454     GET_PROC(BindTexture);
455 
456     if (version >= GR_GL_VER(3,0)) {
457         GET_PROC(BindVertexArray);
458         GET_PROC(DeleteVertexArrays);
459         GET_PROC(GenVertexArrays);
460     } else if (extensions.has("GL_OES_vertex_array_object")) {
461         GET_PROC_SUFFIX(BindVertexArray, OES);
462         GET_PROC_SUFFIX(DeleteVertexArrays, OES);
463         GET_PROC_SUFFIX(GenVertexArrays, OES);
464     }
465 
466     if (version >= GR_GL_VER(3,0) && extensions.has("GL_EXT_blend_func_extended")) {
467         GET_PROC_SUFFIX(BindFragDataLocation, EXT);
468         GET_PROC_SUFFIX(BindFragDataLocationIndexed, EXT);
469     }
470 
471     if (extensions.has("GL_KHR_blend_equation_advanced")) {
472         GET_PROC_SUFFIX(BlendBarrier, KHR);
473     } else if (extensions.has("GL_NV_blend_equation_advanced")) {
474         GET_PROC_SUFFIX(BlendBarrier, NV);
475     }
476 
477     GET_PROC(BlendColor);
478     GET_PROC(BlendEquation);
479     GET_PROC(BlendFunc);
480     GET_PROC(BufferData);
481     GET_PROC(BufferSubData);
482     GET_PROC(Clear);
483     GET_PROC(ClearColor);
484     GET_PROC(ClearStencil);
485     if (extensions.has("GL_EXT_clear_texture")) {
486         GET_PROC_SUFFIX(ClearTexImage, EXT);
487         GET_PROC_SUFFIX(ClearTexSubImage, EXT);
488     }
489     GET_PROC(ColorMask);
490     GET_PROC(CompileShader);
491     GET_PROC(CompressedTexImage2D);
492     GET_PROC(CompressedTexSubImage2D);
493     GET_PROC(CopyTexSubImage2D);
494     GET_PROC(CreateProgram);
495     GET_PROC(CreateShader);
496     GET_PROC(CullFace);
497     GET_PROC(DeleteBuffers);
498     GET_PROC(DeleteProgram);
499     GET_PROC(DeleteShader);
500     GET_PROC(DeleteTextures);
501     GET_PROC(DepthMask);
502     GET_PROC(Disable);
503     GET_PROC(DisableVertexAttribArray);
504     GET_PROC(DrawArrays);
505 
506     if (version >= GR_GL_VER(3,0)) {
507         GET_PROC(DrawArraysInstanced);
508         GET_PROC(DrawBuffers);
509         GET_PROC(DrawElementsInstanced);
510     } else if (extensions.has("GL_EXT_draw_instanced")) {
511         GET_PROC_SUFFIX(DrawArraysInstanced, EXT);
512         GET_PROC_SUFFIX(DrawElementsInstanced, EXT);
513     }
514 
515     if (version >= GR_GL_VER(3,1)) {
516         GET_PROC(DrawArraysIndirect);
517         GET_PROC(DrawElementsIndirect);
518     }
519 
520     GET_PROC(DrawElements);
521     if (version >= GR_GL_VER(3,0)) {
522         GET_PROC(DrawRangeElements);
523     }
524     GET_PROC(Enable);
525     GET_PROC(EnableVertexAttribArray);
526     GET_PROC(Finish);
527     GET_PROC(Flush);
528     GET_PROC(FrontFace);
529     GET_PROC(GenBuffers);
530     GET_PROC(GenerateMipmap);
531     GET_PROC(GenTextures);
532     GET_PROC(GetBufferParameteriv);
533     GET_PROC(GetError);
534     GET_PROC(GetIntegerv);
535 
536     if (version >= GR_GL_VER(3,1)) {
537         GET_PROC(GetMultisamplefv);
538     }
539 
540     GET_PROC(GetProgramInfoLog);
541     GET_PROC(GetProgramiv);
542     GET_PROC(GetShaderInfoLog);
543     GET_PROC(GetShaderPrecisionFormat);
544     GET_PROC(GetShaderiv);
545     GET_PROC(GetString);
546     GET_PROC(GetStringi);
547     if (version >= GR_GL_VER(3,1)) {
548         GET_PROC(GetTexLevelParameteriv);
549     }
550     GET_PROC(GetUniformLocation);
551     GET_PROC(IsTexture);
552     GET_PROC(LineWidth);
553     GET_PROC(LinkProgram);
554 
555     if (extensions.has("GL_EXT_multi_draw_indirect")) {
556         GET_PROC_SUFFIX(MultiDrawArraysIndirect, EXT);
557         GET_PROC_SUFFIX(MultiDrawElementsIndirect, EXT);
558     }
559 
560     GET_PROC(PixelStorei);
561 
562     if (extensions.has("GL_EXT_raster_multisample")) {
563         GET_PROC_SUFFIX(RasterSamples, EXT);
564     }
565 
566     if (version >= GR_GL_VER(3,0)) {
567         GET_PROC(ReadBuffer);
568     }
569     GET_PROC(ReadPixels);
570     GET_PROC(Scissor);
571     GET_PROC(ShaderSource);
572     GET_PROC(StencilFunc);
573     GET_PROC(StencilFuncSeparate);
574     GET_PROC(StencilMask);
575     GET_PROC(StencilMaskSeparate);
576     GET_PROC(StencilOp);
577     GET_PROC(StencilOpSeparate);
578 
579     if (version >= GR_GL_VER(3,2)) {
580         GET_PROC(TexBuffer);
581         GET_PROC(TexBufferRange);
582     } else if (extensions.has("GL_OES_texture_buffer")) {
583         GET_PROC_SUFFIX(TexBuffer, OES);
584         GET_PROC_SUFFIX(TexBufferRange, OES);
585     } else if (extensions.has("GL_EXT_texture_buffer")) {
586         GET_PROC_SUFFIX(TexBuffer, EXT);
587         GET_PROC_SUFFIX(TexBufferRange, EXT);
588     }
589 
590     GET_PROC(TexImage2D);
591     GET_PROC(TexParameterf);
592     GET_PROC(TexParameterfv);
593     GET_PROC(TexParameteri);
594     GET_PROC(TexParameteriv);
595     GET_PROC(TexSubImage2D);
596 
597     if (version >= GR_GL_VER(3,0)) {
598         GET_PROC(TexStorage2D);
599     } else {
600         GET_PROC_SUFFIX(TexStorage2D, EXT);
601     }
602 
603     if (extensions.has("GL_NV_texture_barrier")) {
604         GET_PROC_SUFFIX(TextureBarrier, NV);
605     }
606 
607     GET_PROC_SUFFIX(DiscardFramebuffer, EXT);
608     GET_PROC(Uniform1f);
609     GET_PROC(Uniform1i);
610     GET_PROC(Uniform1fv);
611     GET_PROC(Uniform1iv);
612     GET_PROC(Uniform2f);
613     GET_PROC(Uniform2i);
614     GET_PROC(Uniform2fv);
615     GET_PROC(Uniform2iv);
616     GET_PROC(Uniform3f);
617     GET_PROC(Uniform3i);
618     GET_PROC(Uniform3fv);
619     GET_PROC(Uniform3iv);
620     GET_PROC(Uniform4f);
621     GET_PROC(Uniform4i);
622     GET_PROC(Uniform4fv);
623     GET_PROC(Uniform4iv);
624     GET_PROC(UniformMatrix2fv);
625     GET_PROC(UniformMatrix3fv);
626     GET_PROC(UniformMatrix4fv);
627     GET_PROC(UseProgram);
628     GET_PROC(VertexAttrib1f);
629     GET_PROC(VertexAttrib2fv);
630     GET_PROC(VertexAttrib3fv);
631     GET_PROC(VertexAttrib4fv);
632 
633     if (version >= GR_GL_VER(3,0)) {
634         GET_PROC(VertexAttribDivisor);
635     } else if (extensions.has("GL_EXT_instanced_arrays")) {
636         GET_PROC_SUFFIX(VertexAttribDivisor, EXT);
637     }
638 
639     if (version >= GR_GL_VER(3,0)) {
640         GET_PROC(VertexAttribIPointer);
641     }
642 
643     GET_PROC(VertexAttribPointer);
644     GET_PROC(Viewport);
645     GET_PROC(BindFramebuffer);
646     GET_PROC(BindRenderbuffer);
647     GET_PROC(CheckFramebufferStatus);
648     GET_PROC(DeleteFramebuffers);
649     GET_PROC(DeleteRenderbuffers);
650     GET_PROC(FramebufferRenderbuffer);
651     GET_PROC(FramebufferTexture2D);
652 
653     if (version >= GR_GL_VER(3,0)) {
654         GET_PROC(RenderbufferStorageMultisample);
655         GET_PROC(BlitFramebuffer);
656     } else if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) {
657         GET_PROC_SUFFIX(RenderbufferStorageMultisample, CHROMIUM);
658         GET_PROC_SUFFIX(BlitFramebuffer, CHROMIUM);
659     } else {
660         if (extensions.has("GL_ANGLE_framebuffer_multisample")) {
661             GET_PROC_SUFFIX(RenderbufferStorageMultisample, ANGLE);
662         }
663         if (extensions.has("GL_ANGLE_framebuffer_blit")) {
664             GET_PROC_SUFFIX(BlitFramebuffer, ANGLE);
665         }
666     }
667 
668     if (extensions.has("GL_CHROMIUM_map_sub")) {
669         GET_PROC_SUFFIX(MapBufferSubData, CHROMIUM);
670         GET_PROC_SUFFIX(MapTexSubImage2D, CHROMIUM);
671         GET_PROC_SUFFIX(UnmapBufferSubData, CHROMIUM);
672         GET_PROC_SUFFIX(UnmapTexSubImage2D, CHROMIUM);
673     }
674 
675     if (extensions.has("GL_EXT_multisampled_render_to_texture")) {
676         GET_PROC_SUFFIX(FramebufferTexture2DMultisample, EXT);
677         functions->fRenderbufferStorageMultisampleES2EXT =
678                 (GrGLRenderbufferStorageMultisampleFn*)get(ctx,
679                                                            "glRenderbufferStorageMultisampleEXT");
680     } else if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
681         GET_PROC_SUFFIX(FramebufferTexture2DMultisample, IMG);
682         functions->fRenderbufferStorageMultisampleES2EXT =
683                 (GrGLRenderbufferStorageMultisampleFn*)get(ctx,
684                                                            "glRenderbufferStorageMultisampleIMG");
685     } else if (extensions.has("GL_APPLE_framebuffer_multisample")) {
686         functions->fRenderbufferStorageMultisampleES2APPLE =
687                 (GrGLRenderbufferStorageMultisampleFn*)get(ctx,
688                                                            "glRenderbufferStorageMultisampleAPPLE");
689         GET_PROC_SUFFIX(ResolveMultisampleFramebuffer, APPLE);
690     }
691 
692     GET_PROC(GenFramebuffers);
693     GET_PROC(GenRenderbuffers);
694     GET_PROC(GetFramebufferAttachmentParameteriv);
695     GET_PROC(GetRenderbufferParameteriv);
696     GET_PROC(RenderbufferStorage);
697 
698     // There are several APIs for buffer mapping:
699     // ES2 + GL_OES_mapbuffer: MapBufferOES and UnmapBufferOES
700     // ES2 + GL_EXT_map_buffer_range: Adds MapBufferRangeEXT and FlushMappedBufferRangeEXT
701     // ES3: MapBufferRange, FlushMappedBufferRange, and UnmapBuffer are core (so no suffix).
702     //
703     // MapBuffer is not part of ES3, but implementations may still report the OES versions of
704     // MapBuffer and UnmapBuffer, per the older GL_OES_mapbuffer extension. Some implementations
705     // let us mix the newer MapBufferRange with the older UnmapBufferOES, but we've hit others that
706     // don't permit it. Note that in GrGLBuffer, we choose which API to use based on version and
707     // extensions. This code is written so that we never mix OES and non-OES functions.
708     GET_PROC_SUFFIX(MapBuffer, OES);
709     if (version >= GR_GL_VER(3, 0)) {
710         GET_PROC(UnmapBuffer);
711     } else {
712         GET_PROC_SUFFIX(UnmapBuffer, OES);
713     }
714 
715     if (version >= GR_GL_VER(3,0)) {
716         GET_PROC(MapBufferRange);
717         GET_PROC(FlushMappedBufferRange);
718     } else if (extensions.has("GL_EXT_map_buffer_range")) {
719         GET_PROC_SUFFIX(MapBufferRange, EXT);
720         GET_PROC_SUFFIX(FlushMappedBufferRange, EXT);
721     }
722 
723     if (extensions.has("GL_EXT_debug_marker")) {
724         GET_PROC_SUFFIX(InsertEventMarker, EXT);
725         GET_PROC_SUFFIX(PushGroupMarker, EXT);
726         GET_PROC_SUFFIX(PopGroupMarker, EXT);
727     }
728 
729     GET_PROC(InvalidateFramebuffer);
730     GET_PROC(InvalidateSubFramebuffer);
731     GET_PROC(InvalidateBufferData);
732     GET_PROC(InvalidateBufferSubData);
733     GET_PROC(InvalidateTexImage);
734     GET_PROC(InvalidateTexSubImage);
735 
736     if (version >= GR_GL_VER(3,1)) {
737         GET_PROC(GetProgramResourceLocation);
738     }
739 
740     if (extensions.has("GL_NV_path_rendering")) {
741         GET_PROC_SUFFIX(MatrixLoadf, EXT);
742         GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
743         GET_PROC_SUFFIX(PathCommands, NV);
744         GET_PROC_SUFFIX(PathParameteri, NV);
745         GET_PROC_SUFFIX(PathParameterf, NV);
746         GET_PROC_SUFFIX(GenPaths, NV);
747         GET_PROC_SUFFIX(DeletePaths, NV);
748         GET_PROC_SUFFIX(IsPath, NV);
749         GET_PROC_SUFFIX(PathStencilFunc, NV);
750         GET_PROC_SUFFIX(StencilFillPath, NV);
751         GET_PROC_SUFFIX(StencilStrokePath, NV);
752         GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
753         GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
754         GET_PROC_SUFFIX(CoverFillPath, NV);
755         GET_PROC_SUFFIX(CoverStrokePath, NV);
756         GET_PROC_SUFFIX(CoverFillPathInstanced, NV);
757         GET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
758         GET_PROC_SUFFIX(StencilThenCoverFillPath, NV);
759         GET_PROC_SUFFIX(StencilThenCoverStrokePath, NV);
760         GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, NV);
761         GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, NV);
762         GET_PROC_SUFFIX(ProgramPathFragmentInputGen, NV);
763     }
764 
765     if (extensions.has("GL_CHROMIUM_path_rendering")) {
766         GET_PROC_SUFFIX(MatrixLoadf, CHROMIUM);
767         GET_PROC_SUFFIX(MatrixLoadIdentity, CHROMIUM);
768         GET_PROC_SUFFIX(PathCommands, CHROMIUM);
769         GET_PROC_SUFFIX(PathParameteri, CHROMIUM);
770         GET_PROC_SUFFIX(PathParameterf, CHROMIUM);
771         GET_PROC_SUFFIX(GenPaths, CHROMIUM);
772         GET_PROC_SUFFIX(DeletePaths, CHROMIUM);
773         GET_PROC_SUFFIX(IsPath, CHROMIUM);
774         GET_PROC_SUFFIX(PathStencilFunc, CHROMIUM);
775         GET_PROC_SUFFIX(StencilFillPath, CHROMIUM);
776         GET_PROC_SUFFIX(StencilStrokePath, CHROMIUM);
777         GET_PROC_SUFFIX(StencilFillPathInstanced, CHROMIUM);
778         GET_PROC_SUFFIX(StencilStrokePathInstanced, CHROMIUM);
779         GET_PROC_SUFFIX(CoverFillPath, CHROMIUM);
780         GET_PROC_SUFFIX(CoverStrokePath, CHROMIUM);
781         GET_PROC_SUFFIX(CoverFillPathInstanced, CHROMIUM);
782         GET_PROC_SUFFIX(CoverStrokePathInstanced, CHROMIUM);
783         GET_PROC_SUFFIX(StencilThenCoverFillPath, CHROMIUM);
784         GET_PROC_SUFFIX(StencilThenCoverStrokePath, CHROMIUM);
785         GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, CHROMIUM);
786         GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, CHROMIUM);
787         GET_PROC_SUFFIX(ProgramPathFragmentInputGen, CHROMIUM);
788         // GL_CHROMIUM_path_rendering additions:
789         GET_PROC_SUFFIX(BindFragmentInputLocation, CHROMIUM);
790     }
791 
792     if (extensions.has("GL_NV_framebuffer_mixed_samples")) {
793         GET_PROC_SUFFIX(CoverageModulation, NV);
794     }
795     if (extensions.has("GL_CHROMIUM_framebuffer_mixed_samples")) {
796         GET_PROC_SUFFIX(CoverageModulation, CHROMIUM);
797     }
798 
799     if (extensions.has("GL_KHR_debug")) {
800         GET_PROC_SUFFIX(DebugMessageControl, KHR);
801         GET_PROC_SUFFIX(DebugMessageInsert, KHR);
802         GET_PROC_SUFFIX(DebugMessageCallback, KHR);
803         GET_PROC_SUFFIX(GetDebugMessageLog, KHR);
804         GET_PROC_SUFFIX(PushDebugGroup, KHR);
805         GET_PROC_SUFFIX(PopDebugGroup, KHR);
806         GET_PROC_SUFFIX(ObjectLabel, KHR);
807         // In general we have a policy against removing extension strings when the driver does
808         // not provide function pointers for an advertised extension. However, because there is a
809         // known device that advertises GL_KHR_debug but fails to provide the functions and this is
810         // a debugging- only extension we've made an exception. This also can happen when using
811         // APITRACE.
812         if (!interface->fFunctions.fDebugMessageControl) {
813             extensions.remove("GL_KHR_debug");
814         }
815     }
816 
817     if (extensions.has("GL_CHROMIUM_bind_uniform_location")) {
818         GET_PROC_SUFFIX(BindUniformLocation, CHROMIUM);
819     }
820 
821     if (extensions.has("GL_EXT_window_rectangles")) {
822         GET_PROC_SUFFIX(WindowRectangles, EXT);
823     }
824 
825     if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
826         GET_EGL_PROC_SUFFIX(CreateImage, KHR);
827         GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
828     }
829 
830     if (version >= GR_GL_VER(3, 0)) {
831         GET_PROC(FenceSync);
832         GET_PROC(IsSync);
833         GET_PROC(ClientWaitSync);
834         GET_PROC(WaitSync);
835         GET_PROC(DeleteSync);
836     } else if (extensions.has("GL_APPLE_sync")) {
837         GET_PROC_SUFFIX(FenceSync, APPLE);
838         GET_PROC_SUFFIX(IsSync, APPLE);
839         GET_PROC_SUFFIX(ClientWaitSync, APPLE);
840         GET_PROC_SUFFIX(WaitSync, APPLE);
841         GET_PROC_SUFFIX(DeleteSync, APPLE);
842     }
843 
844     if (version >= GR_GL_VER(3,0)) {
845         GET_PROC(GetInternalformativ);
846     }
847 
848     if (version >= GR_GL_VER(3, 0)) {
849         GET_PROC(GetProgramBinary);
850         GET_PROC(ProgramBinary);
851         GET_PROC(ProgramParameteri);
852     }
853 
854     if (version >= GR_GL_VER(3,0)) {
855         GET_PROC(BindSampler);
856         GET_PROC(DeleteSamplers);
857         GET_PROC(GenSamplers);
858         GET_PROC(SamplerParameteri);
859         GET_PROC(SamplerParameteriv);
860     }
861 
862     interface->fStandard = kGLES_GrGLStandard;
863     interface->fExtensions.swap(&extensions);
864 
865     return std::move(interface);
866 }
867 
GrGLAssembleInterface(void * ctx,GrGLGetProc get)868 SK_API const GrGLInterface* GrGLAssembleInterface(void *ctx, GrGLGetProc get) {
869     return GrGLMakeAssembledInterface(ctx, get).release();
870 }
871