c192611f5099a26109bf8a82c6e52e4043cea848
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLInterface.cpp
1 /*
2  * Copyright 2011 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/GrGLInterface.h"
10 #include "gl/GrGLExtensions.h"
11 #include "gl/GrGLUtil.h"
12
13 #include <stdio.h>
14
15 #if GR_GL_PER_GL_FUNC_CALLBACK
16 namespace {
17 void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
18 }
19 #endif
20
21 const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface* interface,
22                                                      GrGLInsertEventMarkerProc insertEventMarkerFn,
23                                                      GrGLPushGroupMarkerProc pushGroupMarkerFn,
24                                                      GrGLPopGroupMarkerProc popGroupMarkerFn) {
25     GrGLInterface* newInterface = GrGLInterface::NewClone(interface);
26
27     if (!newInterface->fExtensions.has("GL_EXT_debug_marker")) {
28         newInterface->fExtensions.add("GL_EXT_debug_marker");
29     }
30
31     newInterface->fFunctions.fInsertEventMarker = insertEventMarkerFn;
32     newInterface->fFunctions.fPushGroupMarker = pushGroupMarkerFn;
33     newInterface->fFunctions.fPopGroupMarker = popGroupMarkerFn;
34
35     return newInterface;
36 }
37
38 const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) {
39     GrGLInterface* newInterface = GrGLInterface::NewClone(interface);
40
41     newInterface->fExtensions.remove("GL_NV_path_rendering");
42     newInterface->fFunctions.fPathCommands = NULL;
43     newInterface->fFunctions.fPathCoords = NULL;
44     newInterface->fFunctions.fPathParameteri = NULL;
45     newInterface->fFunctions.fPathParameterf = NULL;
46     newInterface->fFunctions.fGenPaths = NULL;
47     newInterface->fFunctions.fDeletePaths = NULL;
48     newInterface->fFunctions.fIsPath = NULL;
49     newInterface->fFunctions.fPathStencilFunc = NULL;
50     newInterface->fFunctions.fStencilFillPath = NULL;
51     newInterface->fFunctions.fStencilStrokePath = NULL;
52     newInterface->fFunctions.fStencilFillPathInstanced = NULL;
53     newInterface->fFunctions.fStencilStrokePathInstanced = NULL;
54     newInterface->fFunctions.fPathTexGen = NULL;
55     newInterface->fFunctions.fCoverFillPath = NULL;
56     newInterface->fFunctions.fCoverStrokePath = NULL;
57     newInterface->fFunctions.fCoverFillPathInstanced = NULL;
58     newInterface->fFunctions.fCoverStrokePathInstanced = NULL;
59     newInterface->fFunctions.fStencilThenCoverFillPath = NULL;
60     newInterface->fFunctions.fStencilThenCoverStrokePath = NULL;
61     newInterface->fFunctions.fStencilThenCoverFillPathInstanced = NULL;
62     newInterface->fFunctions.fStencilThenCoverStrokePathInstanced = NULL;
63     newInterface->fFunctions.fProgramPathFragmentInputGen = NULL;
64     return newInterface;
65 }
66
67 GrGLInterface::GrGLInterface() {
68     fStandard = kNone_GrGLStandard;
69
70 #if GR_GL_PER_GL_FUNC_CALLBACK
71     fCallback = GrGLDefaultInterfaceCallback;
72     fCallbackData = 0;
73 #endif
74 }
75
76 GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) {
77     SkASSERT(NULL != interface);
78
79     GrGLInterface* clone = SkNEW(GrGLInterface);
80     clone->fStandard = interface->fStandard;
81     clone->fExtensions = interface->fExtensions;
82     clone->fFunctions = interface->fFunctions;
83 #if GR_GL_PER_GL_FUNC_CALLBACK
84     clone->fCallback = interface->fCallback;
85     clone->fCallbackData = interface->fCallbackData;
86 #endif
87     return clone;
88 }
89
90 #ifdef SK_DEBUG
91     static int kIsDebug = 1;
92 #else
93     static int kIsDebug = 0;
94 #endif
95
96 #define RETURN_FALSE_INTERFACE                                                                   \
97     if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \
98     return false;
99
100 bool GrGLInterface::validate() const {
101
102     if (kNone_GrGLStandard == fStandard) {
103         RETURN_FALSE_INTERFACE
104     }
105
106     if (!fExtensions.isInitialized()) {
107         RETURN_FALSE_INTERFACE
108     }
109
110     // functions that are always required
111     if (NULL == fFunctions.fActiveTexture ||
112         NULL == fFunctions.fAttachShader ||
113         NULL == fFunctions.fBindAttribLocation ||
114         NULL == fFunctions.fBindBuffer ||
115         NULL == fFunctions.fBindTexture ||
116         NULL == fFunctions.fBlendFunc ||
117         NULL == fFunctions.fBlendColor ||      // -> GL >= 1.4, ES >= 2.0 or extension
118         NULL == fFunctions.fBufferData ||
119         NULL == fFunctions.fBufferSubData ||
120         NULL == fFunctions.fClear ||
121         NULL == fFunctions.fClearColor ||
122         NULL == fFunctions.fClearStencil ||
123         NULL == fFunctions.fColorMask ||
124         NULL == fFunctions.fCompileShader ||
125         NULL == fFunctions.fCopyTexSubImage2D ||
126         NULL == fFunctions.fCreateProgram ||
127         NULL == fFunctions.fCreateShader ||
128         NULL == fFunctions.fCullFace ||
129         NULL == fFunctions.fDeleteBuffers ||
130         NULL == fFunctions.fDeleteProgram ||
131         NULL == fFunctions.fDeleteShader ||
132         NULL == fFunctions.fDeleteTextures ||
133         NULL == fFunctions.fDepthMask ||
134         NULL == fFunctions.fDisable ||
135         NULL == fFunctions.fDisableVertexAttribArray ||
136         NULL == fFunctions.fDrawArrays ||
137         NULL == fFunctions.fDrawElements ||
138         NULL == fFunctions.fEnable ||
139         NULL == fFunctions.fEnableVertexAttribArray ||
140         NULL == fFunctions.fFrontFace ||
141         NULL == fFunctions.fGenBuffers ||
142         NULL == fFunctions.fGenTextures ||
143         NULL == fFunctions.fGetBufferParameteriv ||
144         NULL == fFunctions.fGenerateMipmap ||
145         NULL == fFunctions.fGetError ||
146         NULL == fFunctions.fGetIntegerv ||
147         NULL == fFunctions.fGetProgramInfoLog ||
148         NULL == fFunctions.fGetProgramiv ||
149         NULL == fFunctions.fGetShaderInfoLog ||
150         NULL == fFunctions.fGetShaderiv ||
151         NULL == fFunctions.fGetString ||
152         NULL == fFunctions.fGetUniformLocation ||
153         NULL == fFunctions.fLinkProgram ||
154         NULL == fFunctions.fLineWidth ||
155         NULL == fFunctions.fPixelStorei ||
156         NULL == fFunctions.fReadPixels ||
157         NULL == fFunctions.fScissor ||
158         NULL == fFunctions.fShaderSource ||
159         NULL == fFunctions.fStencilFunc ||
160         NULL == fFunctions.fStencilMask ||
161         NULL == fFunctions.fStencilOp ||
162         NULL == fFunctions.fTexImage2D ||
163         NULL == fFunctions.fTexParameteri ||
164         NULL == fFunctions.fTexParameteriv ||
165         NULL == fFunctions.fTexSubImage2D ||
166         NULL == fFunctions.fUniform1f ||
167         NULL == fFunctions.fUniform1i ||
168         NULL == fFunctions.fUniform1fv ||
169         NULL == fFunctions.fUniform1iv ||
170         NULL == fFunctions.fUniform2f ||
171         NULL == fFunctions.fUniform2i ||
172         NULL == fFunctions.fUniform2fv ||
173         NULL == fFunctions.fUniform2iv ||
174         NULL == fFunctions.fUniform3f ||
175         NULL == fFunctions.fUniform3i ||
176         NULL == fFunctions.fUniform3fv ||
177         NULL == fFunctions.fUniform3iv ||
178         NULL == fFunctions.fUniform4f ||
179         NULL == fFunctions.fUniform4i ||
180         NULL == fFunctions.fUniform4fv ||
181         NULL == fFunctions.fUniform4iv ||
182         NULL == fFunctions.fUniformMatrix2fv ||
183         NULL == fFunctions.fUniformMatrix3fv ||
184         NULL == fFunctions.fUniformMatrix4fv ||
185         NULL == fFunctions.fUseProgram ||
186         NULL == fFunctions.fVertexAttrib4fv ||
187         NULL == fFunctions.fVertexAttribPointer ||
188         NULL == fFunctions.fViewport ||
189         NULL == fFunctions.fBindFramebuffer ||
190         NULL == fFunctions.fBindRenderbuffer ||
191         NULL == fFunctions.fCheckFramebufferStatus ||
192         NULL == fFunctions.fDeleteFramebuffers ||
193         NULL == fFunctions.fDeleteRenderbuffers ||
194         NULL == fFunctions.fFinish ||
195         NULL == fFunctions.fFlush ||
196         NULL == fFunctions.fFramebufferRenderbuffer ||
197         NULL == fFunctions.fFramebufferTexture2D ||
198         NULL == fFunctions.fGetFramebufferAttachmentParameteriv ||
199         NULL == fFunctions.fGetRenderbufferParameteriv ||
200         NULL == fFunctions.fGenFramebuffers ||
201         NULL == fFunctions.fGenRenderbuffers ||
202         NULL == fFunctions.fRenderbufferStorage) {
203         RETURN_FALSE_INTERFACE
204     }
205
206     GrGLVersion glVer = GrGLGetVersion(this);
207     if (GR_GL_INVALID_VER == glVer) {
208         RETURN_FALSE_INTERFACE
209     }
210
211     // Now check that baseline ES/Desktop fns not covered above are present
212     // and that we have fn pointers for any advertised fExtensions that we will
213     // try to use.
214
215     // these functions are part of ES2, we assume they are available
216     // On the desktop we assume they are available if the extension
217     // is present or GL version is high enough.
218     if (kGLES_GrGLStandard == fStandard) {
219         if (NULL == fFunctions.fStencilFuncSeparate ||
220             NULL == fFunctions.fStencilMaskSeparate ||
221             NULL == fFunctions.fStencilOpSeparate) {
222             RETURN_FALSE_INTERFACE
223         }
224     } else if (kGL_GrGLStandard == fStandard) {
225
226         if (glVer >= GR_GL_VER(2,0)) {
227             if (NULL == fFunctions.fStencilFuncSeparate ||
228                 NULL == fFunctions.fStencilMaskSeparate ||
229                 NULL == fFunctions.fStencilOpSeparate) {
230                 RETURN_FALSE_INTERFACE
231             }
232         }
233         if (glVer >= GR_GL_VER(3,0) && NULL == fFunctions.fBindFragDataLocation) {
234             RETURN_FALSE_INTERFACE
235         }
236         if (glVer >= GR_GL_VER(2,0) || fExtensions.has("GL_ARB_draw_buffers")) {
237             if (NULL == fFunctions.fDrawBuffers) {
238                 RETURN_FALSE_INTERFACE
239             }
240         }
241
242         if (glVer >= GR_GL_VER(1,5) || fExtensions.has("GL_ARB_occlusion_query")) {
243             if (NULL == fFunctions.fGenQueries ||
244                 NULL == fFunctions.fDeleteQueries ||
245                 NULL == fFunctions.fBeginQuery ||
246                 NULL == fFunctions.fEndQuery ||
247                 NULL == fFunctions.fGetQueryiv ||
248                 NULL == fFunctions.fGetQueryObjectiv ||
249                 NULL == fFunctions.fGetQueryObjectuiv) {
250                 RETURN_FALSE_INTERFACE
251             }
252         }
253         if (glVer >= GR_GL_VER(3,3) ||
254             fExtensions.has("GL_ARB_timer_query") ||
255             fExtensions.has("GL_EXT_timer_query")) {
256             if (NULL == fFunctions.fGetQueryObjecti64v ||
257                 NULL == fFunctions.fGetQueryObjectui64v) {
258                 RETURN_FALSE_INTERFACE
259             }
260         }
261         if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) {
262             if (NULL == fFunctions.fQueryCounter) {
263                 RETURN_FALSE_INTERFACE
264             }
265         }
266     }
267
268     // optional function on desktop before 1.3
269     if (kGL_GrGLStandard != fStandard ||
270         (glVer >= GR_GL_VER(1,3)) ||
271         fExtensions.has("GL_ARB_texture_compression")) {
272         if (NULL == fFunctions.fCompressedTexImage2D
273 #if 0
274             || NULL == fFunctions.fCompressedTexSubImage2D
275 #endif
276             ) {
277             RETURN_FALSE_INTERFACE
278         }
279     }
280
281     // part of desktop GL, but not ES
282     if (kGL_GrGLStandard == fStandard &&
283         (NULL == fFunctions.fGetTexLevelParameteriv ||
284          NULL == fFunctions.fDrawBuffer ||
285          NULL == fFunctions.fReadBuffer)) {
286         RETURN_FALSE_INTERFACE
287     }
288
289     // GL_EXT_texture_storage is part of desktop 4.2
290     // There is a desktop ARB extension and an ES+desktop EXT extension
291     if (kGL_GrGLStandard == fStandard) {
292         if (glVer >= GR_GL_VER(4,2) ||
293             fExtensions.has("GL_ARB_texture_storage") ||
294             fExtensions.has("GL_EXT_texture_storage")) {
295             if (NULL == fFunctions.fTexStorage2D) {
296                 RETURN_FALSE_INTERFACE
297             }
298         }
299     } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) {
300         if (NULL == fFunctions.fTexStorage2D) {
301             RETURN_FALSE_INTERFACE
302         }
303     }
304
305     if (fExtensions.has("GL_EXT_discard_framebuffer")) {
306 // FIXME: Remove this once Chromium is updated to provide this function
307 #if 0
308         if (NULL == fFunctions.fDiscardFramebuffer) {
309             RETURN_FALSE_INTERFACE
310         }
311 #endif
312     }
313
314     // FBO MSAA
315     if (kGL_GrGLStandard == fStandard) {
316         // GL 3.0 and the ARB extension have multisample + blit
317         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) {
318             if (NULL == fFunctions.fRenderbufferStorageMultisample ||
319                 NULL == fFunctions.fBlitFramebuffer) {
320                 RETURN_FALSE_INTERFACE
321             }
322         } else {
323             if (fExtensions.has("GL_EXT_framebuffer_blit") &&
324                 NULL == fFunctions.fBlitFramebuffer) {
325                 RETURN_FALSE_INTERFACE
326             }
327             if (fExtensions.has("GL_EXT_framebuffer_multisample") &&
328                 NULL == fFunctions.fRenderbufferStorageMultisample) {
329                 RETURN_FALSE_INTERFACE
330             }
331         }
332     } else {
333         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) {
334             if (NULL == fFunctions.fRenderbufferStorageMultisample ||
335                 NULL == fFunctions.fBlitFramebuffer) {
336                 RETURN_FALSE_INTERFACE
337             }
338         }
339         if (fExtensions.has("GL_APPLE_framebuffer_multisample")) {
340             if (NULL == fFunctions.fRenderbufferStorageMultisampleES2APPLE ||
341                 NULL == fFunctions.fResolveMultisampleFramebuffer) {
342                 RETURN_FALSE_INTERFACE
343             }
344         }
345         if (fExtensions.has("GL_IMG_multisampled_render_to_texture") ||
346             fExtensions.has("GL_EXT_multisampled_render_to_texture")) {
347             if (NULL == fFunctions.fRenderbufferStorageMultisampleES2EXT ||
348                 NULL == fFunctions.fFramebufferTexture2DMultisample) {
349                 RETURN_FALSE_INTERFACE
350             }
351         }
352     }
353
354     // On ES buffer mapping is an extension. On Desktop
355     // buffer mapping was part of original VBO extension
356     // which we require.
357     if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) {
358         if (NULL == fFunctions.fMapBuffer ||
359             NULL == fFunctions.fUnmapBuffer) {
360             RETURN_FALSE_INTERFACE
361         }
362     }
363
364     // Dual source blending
365     if (kGL_GrGLStandard == fStandard &&
366         (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended"))) {
367         if (NULL == fFunctions.fBindFragDataLocationIndexed) {
368             RETURN_FALSE_INTERFACE
369         }
370     }
371
372     // glGetStringi was added in version 3.0 of both desktop and ES.
373     if (glVer >= GR_GL_VER(3, 0)) {
374         if (NULL == fFunctions.fGetStringi) {
375             RETURN_FALSE_INTERFACE
376         }
377     }
378
379     if (kGL_GrGLStandard == fStandard) {
380         if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) {
381             if (NULL == fFunctions.fBindVertexArray ||
382                 NULL == fFunctions.fDeleteVertexArrays ||
383                 NULL == fFunctions.fGenVertexArrays) {
384                 RETURN_FALSE_INTERFACE
385             }
386         }
387     } else {
388         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) {
389             if (NULL == fFunctions.fBindVertexArray ||
390                 NULL == fFunctions.fDeleteVertexArrays ||
391                 NULL == fFunctions.fGenVertexArrays) {
392                 RETURN_FALSE_INTERFACE
393             }
394         }
395     }
396
397     if (fExtensions.has("GL_EXT_debug_marker")) {
398         if (NULL == fFunctions.fInsertEventMarker ||
399             NULL == fFunctions.fPushGroupMarker ||
400             NULL == fFunctions.fPopGroupMarker) {
401             RETURN_FALSE_INTERFACE
402         }
403     }
404
405     if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
406         fExtensions.has("GL_ARB_invalidate_subdata")) {
407         if (NULL == fFunctions.fInvalidateBufferData ||
408             NULL == fFunctions.fInvalidateBufferSubData ||
409             NULL == fFunctions.fInvalidateFramebuffer ||
410             NULL == fFunctions.fInvalidateSubFramebuffer ||
411             NULL == fFunctions.fInvalidateTexImage ||
412             NULL == fFunctions.fInvalidateTexSubImage) {
413             RETURN_FALSE_INTERFACE;
414         }
415     } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
416         // ES 3.0 adds the framebuffer functions but not the others.
417         if (NULL == fFunctions.fInvalidateFramebuffer ||
418             NULL == fFunctions.fInvalidateSubFramebuffer) {
419             RETURN_FALSE_INTERFACE;
420         }
421     }
422
423     if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_CHROMIUM_map_sub")) {
424         if (NULL == fFunctions.fMapBufferSubData ||
425             NULL == fFunctions.fMapTexSubImage2D ||
426             NULL == fFunctions.fUnmapBufferSubData ||
427             NULL == fFunctions.fUnmapTexSubImage2D) {
428             RETURN_FALSE_INTERFACE;
429         }
430     }
431
432     // These functions are added to the 3.0 version of both GLES and GL.
433     if (glVer >= GR_GL_VER(3,0) ||
434         (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) ||
435         (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) {
436         if (NULL == fFunctions.fMapBufferRange ||
437             NULL == fFunctions.fFlushMappedBufferRange) {
438             RETURN_FALSE_INTERFACE;
439         }
440     }
441
442     if ((kGL_GrGLStandard == fStandard && fExtensions.has("GL_EXT_direct_state_access")) ||
443         (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_NV_path_rendering"))) {
444         if (NULL == fFunctions.fMatrixLoadf ||
445             NULL == fFunctions.fMatrixLoadIdentity) {
446             RETURN_FALSE_INTERFACE
447         }
448     }
449
450     if ((kGL_GrGLStandard == fStandard &&
451          (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) ||
452         (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
453         if (NULL == fFunctions.fGetProgramResourceLocation) {
454             RETURN_FALSE_INTERFACE
455         }
456     }
457
458     if (fExtensions.has("GL_NV_path_rendering")) {
459         if (NULL == fFunctions.fPathCommands ||
460             NULL == fFunctions.fPathCoords ||
461             NULL == fFunctions.fPathParameteri ||
462             NULL == fFunctions.fPathParameterf ||
463             NULL == fFunctions.fGenPaths ||
464             NULL == fFunctions.fDeletePaths ||
465             NULL == fFunctions.fIsPath ||
466             NULL == fFunctions.fPathStencilFunc ||
467             NULL == fFunctions.fStencilFillPath ||
468             NULL == fFunctions.fStencilStrokePath ||
469             NULL == fFunctions.fStencilFillPathInstanced ||
470             NULL == fFunctions.fStencilStrokePathInstanced ||
471             NULL == fFunctions.fCoverFillPath ||
472             NULL == fFunctions.fCoverStrokePath ||
473             NULL == fFunctions.fCoverFillPathInstanced ||
474             NULL == fFunctions.fCoverStrokePathInstanced) {
475             RETURN_FALSE_INTERFACE
476         }
477         if (kGL_GrGLStandard == fStandard) {
478             // Some methods only exist on desktop
479             if (NULL == fFunctions.fPathTexGen) {
480                 RETURN_FALSE_INTERFACE
481             }
482         } else {
483             // All additions through v1.3 exist on GLES
484             if (NULL == fFunctions.fStencilThenCoverFillPath ||
485                 NULL == fFunctions.fStencilThenCoverStrokePath ||
486                 NULL == fFunctions.fStencilThenCoverFillPathInstanced ||
487                 NULL == fFunctions.fStencilThenCoverStrokePathInstanced ||
488                 NULL == fFunctions.fProgramPathFragmentInputGen) {
489                 RETURN_FALSE_INTERFACE
490             }
491         }
492     }
493
494     return true;
495 }