1// Modified from chromium/src/webkit/glue/gl_bindings_skia_cmd_buffer.cc
2
3// Copyright (c) 2011 The Chromium Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6
7#include "gl/GrGLInterface.h"
8#include "gl/GrGLAssembleInterface.h"
9#include "gl/GrGLExtensions.h"
10#include "gl/GrGLUtil.h"
11
12#ifndef GL_GLEXT_PROTOTYPES
13#define GL_GLEXT_PROTOTYPES
14#endif
15
16#include <GLES2/gl2.h>
17#include <GLES2/gl2ext.h>
18
19#include <EGL/egl.h>
20
21static GrGLInterface* create_es_interface(GrGLVersion version,
22                                          GrGLExtensions* extensions) {
23    if (version < GR_GL_VER(2,0)) {
24        return NULL;
25    }
26
27    GrGLInterface* interface = SkNEW(GrGLInterface);
28    interface->fStandard = kGLES_GrGLStandard;
29    GrGLInterface::Functions* functions = &interface->fFunctions;
30
31    functions->fActiveTexture = glActiveTexture;
32    functions->fAttachShader = glAttachShader;
33    functions->fBindAttribLocation = glBindAttribLocation;
34    functions->fBindBuffer = glBindBuffer;
35    functions->fBindTexture = glBindTexture;
36    functions->fBindVertexArray = glBindVertexArrayOES;
37    functions->fBlendColor = glBlendColor;
38    functions->fBlendFunc = glBlendFunc;
39    functions->fBufferData = glBufferData;
40    functions->fBufferSubData = glBufferSubData;
41    functions->fClear = glClear;
42    functions->fClearColor = glClearColor;
43    functions->fClearStencil = glClearStencil;
44    functions->fColorMask = glColorMask;
45    functions->fCompileShader = glCompileShader;
46    functions->fCompressedTexImage2D = glCompressedTexImage2D;
47    functions->fCompressedTexSubImage2D = glCompressedTexSubImage2D;
48    functions->fCopyTexSubImage2D = glCopyTexSubImage2D;
49    functions->fCreateProgram = glCreateProgram;
50    functions->fCreateShader = glCreateShader;
51    functions->fCullFace = glCullFace;
52    functions->fDeleteBuffers = glDeleteBuffers;
53    functions->fDeleteProgram = glDeleteProgram;
54    functions->fDeleteShader = glDeleteShader;
55    functions->fDeleteTextures = glDeleteTextures;
56    functions->fDeleteVertexArrays = glDeleteVertexArraysOES;
57    functions->fDepthMask = glDepthMask;
58    functions->fDisable = glDisable;
59    functions->fDisableVertexAttribArray = glDisableVertexAttribArray;
60    functions->fDrawArrays = glDrawArrays;
61    functions->fDrawElements = glDrawElements;
62    functions->fEnable = glEnable;
63    functions->fEnableVertexAttribArray = glEnableVertexAttribArray;
64    functions->fFinish = glFinish;
65    functions->fFlush = glFlush;
66    functions->fFrontFace = glFrontFace;
67    functions->fGenBuffers = glGenBuffers;
68    functions->fGenerateMipmap = glGenerateMipmap;
69    functions->fGenTextures = glGenTextures;
70    functions->fGenVertexArrays = glGenVertexArraysOES;
71    functions->fGetBufferParameteriv = glGetBufferParameteriv;
72    functions->fGetError = glGetError;
73    functions->fGetIntegerv = glGetIntegerv;
74    functions->fGetProgramInfoLog = glGetProgramInfoLog;
75    functions->fGetProgramiv = glGetProgramiv;
76    functions->fGetShaderInfoLog = glGetShaderInfoLog;
77    functions->fGetShaderiv = glGetShaderiv;
78    functions->fGetString = glGetString;
79#if GL_ES_VERSION_3_0
80    functions->fGetStringi = glGetStringi;
81#else
82    functions->fGetStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
83#endif
84    functions->fGetUniformLocation = glGetUniformLocation;
85    functions->fLineWidth = glLineWidth;
86    functions->fLinkProgram = glLinkProgram;
87    functions->fPixelStorei = glPixelStorei;
88    functions->fReadPixels = glReadPixels;
89    functions->fScissor = glScissor;
90#if GR_GL_USE_NEW_SHADER_SOURCE_SIGNATURE
91    functions->fShaderSource = (GrGLShaderSourceProc) glShaderSource;
92#else
93    functions->fShaderSource = glShaderSource;
94#endif
95    functions->fStencilFunc = glStencilFunc;
96    functions->fStencilFuncSeparate = glStencilFuncSeparate;
97    functions->fStencilMask = glStencilMask;
98    functions->fStencilMaskSeparate = glStencilMaskSeparate;
99    functions->fStencilOp = glStencilOp;
100    functions->fStencilOpSeparate = glStencilOpSeparate;
101    functions->fTexImage2D = glTexImage2D;
102    functions->fTexParameteri = glTexParameteri;
103    functions->fTexParameteriv = glTexParameteriv;
104    functions->fTexSubImage2D = glTexSubImage2D;
105
106    if (version >= GR_GL_VER(3,0)) {
107#if GL_ES_VERSION_3_0
108        functions->fTexStorage2D = glTexStorage2D;
109#else
110        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2D");
111#endif
112    } else {
113#if GL_EXT_texture_storage
114        functions->fTexStorage2D = glTexStorage2DEXT;
115#else
116        functions->fTexStorage2D = (GrGLTexStorage2DProc) eglGetProcAddress("glTexStorage2DEXT");
117#endif
118    }
119
120#if GL_EXT_discard_framebuffer
121    functions->fDiscardFramebuffer = glDiscardFramebufferEXT;
122#endif
123    functions->fUniform1f = glUniform1f;
124    functions->fUniform1i = glUniform1i;
125    functions->fUniform1fv = glUniform1fv;
126    functions->fUniform1iv = glUniform1iv;
127    functions->fUniform2f = glUniform2f;
128    functions->fUniform2i = glUniform2i;
129    functions->fUniform2fv = glUniform2fv;
130    functions->fUniform2iv = glUniform2iv;
131    functions->fUniform3f = glUniform3f;
132    functions->fUniform3i = glUniform3i;
133    functions->fUniform3fv = glUniform3fv;
134    functions->fUniform3iv = glUniform3iv;
135    functions->fUniform4f = glUniform4f;
136    functions->fUniform4i = glUniform4i;
137    functions->fUniform4fv = glUniform4fv;
138    functions->fUniform4iv = glUniform4iv;
139    functions->fUniformMatrix2fv = glUniformMatrix2fv;
140    functions->fUniformMatrix3fv = glUniformMatrix3fv;
141    functions->fUniformMatrix4fv = glUniformMatrix4fv;
142    functions->fUseProgram = glUseProgram;
143    functions->fVertexAttrib4fv = glVertexAttrib4fv;
144    functions->fVertexAttribPointer = glVertexAttribPointer;
145    functions->fViewport = glViewport;
146    functions->fBindFramebuffer = glBindFramebuffer;
147    functions->fBindRenderbuffer = glBindRenderbuffer;
148    functions->fCheckFramebufferStatus = glCheckFramebufferStatus;
149    functions->fDeleteFramebuffers = glDeleteFramebuffers;
150    functions->fDeleteRenderbuffers = glDeleteRenderbuffers;
151    functions->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
152    functions->fFramebufferTexture2D = glFramebufferTexture2D;
153
154    if (version >= GR_GL_VER(3,0)) {
155#if GL_ES_VERSION_3_0
156        functions->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
157        functions->fBlitFramebuffer = glBlitFramebuffer;
158#else
159        functions->fRenderbufferStorageMultisample = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisample");
160        functions->fBlitFramebuffer = (GrGLBlitFramebufferProc) eglGetProcAddress("glBlitFramebuffer");
161#endif
162    }
163
164    if (extensions->has("GL_EXT_multisampled_render_to_texture")) {
165#if GL_EXT_multisampled_render_to_texture
166        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleEXT;
167        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleEXT;
168#else
169        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleEXT");
170        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleEXT");
171#endif
172    } else if (extensions->has("GL_IMG_multisampled_render_to_texture")) {
173#if GL_IMG_multisampled_render_to_texture
174        functions->fFramebufferTexture2DMultisample = glFramebufferTexture2DMultisampleIMG;
175        functions->fRenderbufferStorageMultisampleES2EXT = glRenderbufferStorageMultisampleIMG;
176#else
177        functions->fFramebufferTexture2DMultisample = (GrGLFramebufferTexture2DMultisampleProc) eglGetProcAddress("glFramebufferTexture2DMultisampleIMG");
178        functions->fRenderbufferStorageMultisampleES2EXT = (GrGLRenderbufferStorageMultisampleProc) eglGetProcAddress("glRenderbufferStorageMultisampleIMG");
179#endif
180    }
181
182    functions->fGenFramebuffers = glGenFramebuffers;
183    functions->fGenRenderbuffers = glGenRenderbuffers;
184    functions->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
185    functions->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
186    functions->fRenderbufferStorage = glRenderbufferStorage;
187
188#if GL_OES_mapbuffer
189    functions->fMapBuffer = glMapBufferOES;
190    functions->fUnmapBuffer = glUnmapBufferOES;
191#else
192    functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
193    functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");
194
195#endif
196
197    if (version >= GR_GL_VER(3,0)) {
198#if GL_ES_VERSION_3_0
199        functions->fMapBufferRange = glMapBufferRange;
200        functions->fFlushMappedBufferRange = glFlushMappedBufferRange;
201#else
202        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRange");
203        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRange");
204#endif
205    } else if (extensions->has("GL_EXT_map_buffer_range")) {
206#if GL_EXT_map_buffer_range
207        functions->fMapBufferRange = glMapBufferRangeEXT;
208        functions->fFlushMappedBufferRange = glFlushMappedBufferRangeEXT;
209#else
210        functions->fMapBufferRange = (GrGLMapBufferRangeProc) eglGetProcAddress("glMapBufferRangeEXT");
211        functions->fFlushMappedBufferRange = (GrGLFlushMappedBufferRangeProc) eglGetProcAddress("glFlushMappedBufferRangeEXT");
212#endif
213    }
214
215    if (extensions->has("GL_EXT_debug_marker")) {
216        functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarker");
217        functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarker");
218        functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGroupMarker");
219        // The below check is here because a device has been found that has the extension string but
220        // returns NULL from the eglGetProcAddress for the functions
221        if (NULL == functions->fInsertEventMarker ||
222            NULL == functions->fPushGroupMarker ||
223            NULL == functions->fPopGroupMarker) {
224            extensions->remove("GL_EXT_debug_marker");
225        }
226    }
227
228#if GL_ES_VERSION_3_0
229    functions->fInvalidateFramebuffer = glInvalidateFramebuffer;
230    functions->fInvalidateSubFramebuffer = glInvalidateSubFramebuffer;
231#else
232    functions->fInvalidateFramebuffer = (GrGLInvalidateFramebufferProc) eglGetProcAddress("glInvalidateFramebuffer");
233    functions->fInvalidateSubFramebuffer = (GrGLInvalidateSubFramebufferProc) eglGetProcAddress("glInvalidateSubFramebuffer");
234#endif
235    functions->fInvalidateBufferData = (GrGLInvalidateBufferDataProc) eglGetProcAddress("glInvalidateBufferData");
236    functions->fInvalidateBufferSubData = (GrGLInvalidateBufferSubDataProc) eglGetProcAddress("glInvalidateBufferSubData");
237    functions->fInvalidateTexImage = (GrGLInvalidateTexImageProc) eglGetProcAddress("glInvalidateTexImage");
238    functions->fInvalidateTexSubImage = (GrGLInvalidateTexSubImageProc) eglGetProcAddress("glInvalidateTexSubImage");
239
240    return interface;
241}
242
243static GrGLFuncPtr android_get_gl_proc(void* ctx, const char name[]) {
244    SkASSERT(NULL == ctx);
245    return eglGetProcAddress(name);
246}
247
248static const GrGLInterface* create_desktop_interface() {
249    return GrGLAssembleGLInterface(NULL, android_get_gl_proc);
250}
251
252const GrGLInterface* GrGLCreateNativeInterface() {
253
254    const char* verStr = reinterpret_cast<const char*>(glGetString(GR_GL_VERSION));
255    GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
256
257    if (kGLES_GrGLStandard == standard) {
258        GrGLVersion version = GrGLGetVersionFromString(verStr);
259        GrGLExtensions extensions;
260        GrGLGetStringiProc getStringi = (GrGLGetStringiProc) eglGetProcAddress("glGetStringi");
261        if (!extensions.init(standard, glGetString, getStringi, glGetIntegerv)) {
262            return NULL;
263        }
264        GrGLInterface* interface = create_es_interface(version, &extensions);
265
266        if (NULL != interface) {
267            interface->fExtensions.swap(&extensions);
268        }
269
270        return interface;
271    } else if (kGL_GrGLStandard == standard) {
272        return create_desktop_interface();
273    }
274
275    return NULL;
276}
277