Bug 1860959 [wpt PR 42048] - [webaudio] Convert test to testharness, a=testonly
[gecko.git] / gfx / gl / GLContext.h
blob98a99056fbec049a6751a9e55a950eef37ecc716
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef GLCONTEXT_H_
8 #define GLCONTEXT_H_
10 #include <bitset>
11 #include <stdint.h>
12 #include <stdio.h>
13 #include <stack>
14 #include <vector>
16 #ifdef DEBUG
17 # include <string.h>
18 #endif
20 #ifdef GetClassName
21 # undef GetClassName
22 #endif
24 // Define MOZ_GL_DEBUG_BUILD unconditionally to enable GL debugging in opt
25 // builds.
26 #ifdef DEBUG
27 # define MOZ_GL_DEBUG_BUILD 1
28 #endif
30 #include "mozilla/IntegerRange.h"
31 #include "mozilla/RefPtr.h"
32 #include "mozilla/UniquePtr.h"
33 #include "mozilla/ThreadLocal.h"
35 #include "MozFramebuffer.h"
36 #include "nsTArray.h"
37 #include "GLConsts.h"
38 #include "GLDefs.h"
39 #include "GLTypes.h"
40 #include "GLVendor.h"
41 #include "nsRegionFwd.h"
42 #include "nsString.h"
43 #include "GLContextTypes.h"
44 #include "GLContextSymbols.h"
45 #include "base/platform_thread.h" // for PlatformThreadId
46 #include "mozilla/GenericRefCounted.h"
47 #include "mozilla/WeakPtr.h"
49 #ifdef MOZ_WIDGET_ANDROID
50 # include "mozilla/ProfilerLabels.h"
51 #endif
53 namespace mozilla {
55 namespace gl {
56 class GLBlitHelper;
57 class GLLibraryEGL;
58 class GLReadTexImageHelper;
59 class SharedSurface;
60 class SymbolLoader;
61 struct SymLoadStruct;
62 } // namespace gl
64 namespace layers {
65 class ColorTextureLayerProgram;
66 } // namespace layers
68 namespace widget {
69 class CompositorWidget;
70 } // namespace widget
71 } // namespace mozilla
73 namespace mozilla {
74 namespace gl {
76 enum class GLFeature {
77 bind_buffer_offset,
78 blend_minmax,
79 clear_buffers,
80 copy_buffer,
81 depth_texture,
82 draw_buffers,
83 draw_buffers_indexed,
84 draw_instanced,
85 element_index_uint,
86 ES2_compatibility,
87 ES3_compatibility,
88 EXT_color_buffer_float,
89 frag_color_float,
90 frag_depth,
91 framebuffer_blit,
92 framebuffer_multisample,
93 framebuffer_object,
94 framebuffer_object_EXT_OES,
95 get_integer_indexed,
96 get_integer64_indexed,
97 get_query_object_i64v,
98 get_query_object_iv,
99 gpu_shader4,
100 instanced_arrays,
101 instanced_non_arrays,
102 internalformat_query,
103 invalidate_framebuffer,
104 map_buffer_range,
105 multiview,
106 occlusion_query,
107 occlusion_query_boolean,
108 occlusion_query2,
109 packed_depth_stencil,
110 prim_restart,
111 prim_restart_fixed,
112 provoking_vertex,
113 query_counter,
114 query_objects,
115 query_time_elapsed,
116 read_buffer,
117 renderbuffer_color_float,
118 renderbuffer_color_half_float,
119 robust_buffer_access_behavior,
120 robustness,
121 sRGB,
122 sampler_objects,
123 seamless_cube_map_opt_in,
124 shader_texture_lod,
125 split_framebuffer,
126 standard_derivatives,
127 sync,
128 texture_3D,
129 texture_3D_compressed,
130 texture_3D_copy,
131 texture_compression_bptc,
132 texture_compression_rgtc,
133 texture_float,
134 texture_float_linear,
135 texture_half_float,
136 texture_half_float_linear,
137 texture_non_power_of_two,
138 texture_norm16,
139 texture_rg,
140 texture_storage,
141 texture_swizzle,
142 transform_feedback2,
143 uniform_buffer_object,
144 uniform_matrix_nonsquare,
145 vertex_array_object,
146 EnumMax
149 enum class ContextProfile : uint8_t {
150 Unknown = 0,
151 OpenGLCore,
152 OpenGLCompatibility,
153 OpenGLES
156 enum class GLRenderer {
157 Adreno200,
158 Adreno205,
159 AdrenoTM200,
160 AdrenoTM205,
161 AdrenoTM305,
162 AdrenoTM320,
163 AdrenoTM330,
164 AdrenoTM420,
165 Mali400MP,
166 Mali450MP,
167 MaliT,
168 SGX530,
169 SGX540,
170 SGX544MP,
171 Tegra,
172 AndroidEmulator,
173 GalliumLlvmpipe,
174 IntelHD3000,
175 MicrosoftBasicRenderDriver,
176 Other
179 class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
180 public:
181 static MOZ_THREAD_LOCAL(const GLContext*) sCurrentContext;
183 const GLContextDesc mDesc;
185 bool mImplicitMakeCurrent = false;
186 bool mUseTLSIsCurrent;
188 class TlsScope final {
189 const WeakPtr<GLContext> mGL;
190 const bool mWasTlsOk;
192 public:
193 explicit TlsScope(GLContext* const gl)
194 : mGL(gl), mWasTlsOk(gl && gl->mUseTLSIsCurrent) {
195 if (mGL) {
196 mGL->mUseTLSIsCurrent = true;
200 ~TlsScope() {
201 if (mGL) {
202 mGL->mUseTLSIsCurrent = mWasTlsOk;
207 // -----------------------------------------------------------------------------
208 // basic getters
209 public:
211 * Returns true if the context is using ANGLE. This should only be overridden
212 * for an ANGLE implementation.
214 virtual bool IsANGLE() const { return false; }
217 * Returns true if the context is using WARP. This should only be overridden
218 * for an ANGLE implementation.
220 virtual bool IsWARP() const { return false; }
222 virtual void GetWSIInfo(nsCString* const out) const = 0;
225 * Return true if we are running on a OpenGL core profile context
227 inline bool IsCoreProfile() const {
228 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
230 return mProfile == ContextProfile::OpenGLCore;
234 * Return true if we are running on a OpenGL compatibility profile context
235 * (legacy profile 2.1 on Max OS X)
237 inline bool IsCompatibilityProfile() const {
238 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
240 return mProfile == ContextProfile::OpenGLCompatibility;
243 inline bool IsGLES() const {
244 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
246 return mProfile == ContextProfile::OpenGLES;
249 inline bool IsAtLeast(ContextProfile profile, unsigned int version) const {
250 MOZ_ASSERT(profile != ContextProfile::Unknown,
251 "IsAtLeast: bad <profile> parameter");
252 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
253 MOZ_ASSERT(mVersion != 0, "unknown context version");
255 if (version > mVersion) {
256 return false;
259 return profile == mProfile;
263 * Return the version of the context.
264 * Example :
265 * If this a OpenGL 2.1, that will return 210
267 inline uint32_t Version() const { return mVersion; }
269 inline uint32_t ShadingLanguageVersion() const {
270 return mShadingLanguageVersion;
273 GLVendor Vendor() const { return mVendor; }
274 GLRenderer Renderer() const { return mRenderer; }
275 bool IsMesa() const { return mIsMesa; }
277 bool IsContextLost() const { return mContextLost; }
279 bool CheckContextLost() const {
280 mTopError = GetError();
281 return IsContextLost();
284 bool HasPBOState() const { return (!IsGLES() || Version() >= 300); }
287 * If this context is double-buffered, returns TRUE.
289 virtual bool IsDoubleBuffered() const { return false; }
291 virtual GLContextType GetContextType() const = 0;
293 virtual bool IsCurrentImpl() const = 0;
294 virtual bool MakeCurrentImpl() const = 0;
296 bool IsCurrent() const {
297 if (mImplicitMakeCurrent) return MakeCurrent();
299 return IsCurrentImpl();
302 bool MakeCurrent(bool aForce = false) const;
305 * Get the default framebuffer for this context.
307 UniquePtr<MozFramebuffer> mOffscreenDefaultFb;
309 bool CreateOffscreenDefaultFb(const gfx::IntSize& size);
311 virtual GLuint GetDefaultFramebuffer() {
312 if (mOffscreenDefaultFb) {
313 return mOffscreenDefaultFb->mFB;
315 return 0;
319 * mVersion store the OpenGL's version, multiplied by 100. For example, if
320 * the context is an OpenGL 2.1 context, mVersion value will be 210.
322 uint32_t mVersion = 0;
323 ContextProfile mProfile = ContextProfile::Unknown;
325 uint32_t mShadingLanguageVersion = 0;
327 GLVendor mVendor = GLVendor::Other;
328 GLRenderer mRenderer = GLRenderer::Other;
329 bool mIsMesa = false;
331 // -----------------------------------------------------------------------------
332 // Extensions management
334 * This mechanism is designed to know if an extension is supported. In the
335 * long term, we would like to only use the extension group queries XXX_* to
336 * have full compatibility with context version and profiles (especialy the
337 * core that officialy don't bring any extensions).
341 * Known GL extensions that can be queried by
342 * IsExtensionSupported. The results of this are cached, and as
343 * such it's safe to use this even in performance critical code.
344 * If you add to this array, remember to add to the string names
345 * in GLContext.cpp.
347 enum GLExtensions {
348 Extension_None = 0,
349 AMD_compressed_ATC_texture,
350 ANGLE_depth_texture,
351 ANGLE_framebuffer_blit,
352 ANGLE_framebuffer_multisample,
353 ANGLE_instanced_arrays,
354 ANGLE_multiview,
355 ANGLE_provoking_vertex,
356 ANGLE_texture_compression_dxt3,
357 ANGLE_texture_compression_dxt5,
358 ANGLE_timer_query,
359 APPLE_client_storage,
360 APPLE_fence,
361 APPLE_framebuffer_multisample,
362 APPLE_sync,
363 APPLE_texture_range,
364 APPLE_vertex_array_object,
365 ARB_ES2_compatibility,
366 ARB_ES3_compatibility,
367 ARB_color_buffer_float,
368 ARB_compatibility,
369 ARB_copy_buffer,
370 ARB_depth_texture,
371 ARB_draw_buffers,
372 ARB_draw_instanced,
373 ARB_framebuffer_object,
374 ARB_framebuffer_sRGB,
375 ARB_geometry_shader4,
376 ARB_half_float_pixel,
377 ARB_instanced_arrays,
378 ARB_internalformat_query,
379 ARB_invalidate_subdata,
380 ARB_map_buffer_range,
381 ARB_occlusion_query2,
382 ARB_pixel_buffer_object,
383 ARB_provoking_vertex,
384 ARB_robust_buffer_access_behavior,
385 ARB_robustness,
386 ARB_sampler_objects,
387 ARB_seamless_cube_map,
388 ARB_shader_texture_lod,
389 ARB_sync,
390 ARB_texture_compression,
391 ARB_texture_compression_bptc,
392 ARB_texture_compression_rgtc,
393 ARB_texture_float,
394 ARB_texture_non_power_of_two,
395 ARB_texture_rectangle,
396 ARB_texture_rg,
397 ARB_texture_storage,
398 ARB_texture_swizzle,
399 ARB_timer_query,
400 ARB_transform_feedback2,
401 ARB_uniform_buffer_object,
402 ARB_vertex_array_object,
403 CHROMIUM_color_buffer_float_rgb,
404 CHROMIUM_color_buffer_float_rgba,
405 EXT_bgra,
406 EXT_blend_minmax,
407 EXT_color_buffer_float,
408 EXT_color_buffer_half_float,
409 EXT_copy_texture,
410 EXT_disjoint_timer_query,
411 EXT_draw_buffers,
412 EXT_draw_buffers2,
413 EXT_draw_instanced,
414 EXT_float_blend,
415 EXT_frag_depth,
416 EXT_framebuffer_blit,
417 EXT_framebuffer_multisample,
418 EXT_framebuffer_object,
419 EXT_framebuffer_sRGB,
420 EXT_gpu_shader4,
421 EXT_map_buffer_range,
422 EXT_multisampled_render_to_texture,
423 EXT_occlusion_query_boolean,
424 EXT_packed_depth_stencil,
425 EXT_provoking_vertex,
426 EXT_read_format_bgra,
427 EXT_robustness,
428 EXT_sRGB,
429 EXT_sRGB_write_control,
430 EXT_shader_texture_lod,
431 EXT_texture_compression_bptc,
432 EXT_texture_compression_dxt1,
433 EXT_texture_compression_rgtc,
434 EXT_texture_compression_s3tc,
435 EXT_texture_compression_s3tc_srgb,
436 EXT_texture_filter_anisotropic,
437 EXT_texture_format_BGRA8888,
438 EXT_texture_norm16,
439 EXT_texture_sRGB,
440 EXT_texture_storage,
441 EXT_timer_query,
442 EXT_transform_feedback,
443 EXT_unpack_subimage,
444 IMG_read_format,
445 IMG_texture_compression_pvrtc,
446 IMG_texture_npot,
447 KHR_debug,
448 KHR_parallel_shader_compile,
449 KHR_robust_buffer_access_behavior,
450 KHR_robustness,
451 KHR_texture_compression_astc_hdr,
452 KHR_texture_compression_astc_ldr,
453 NV_draw_instanced,
454 NV_fence,
455 NV_framebuffer_blit,
456 NV_geometry_program4,
457 NV_half_float,
458 NV_instanced_arrays,
459 NV_primitive_restart,
460 NV_texture_barrier,
461 NV_transform_feedback,
462 NV_transform_feedback2,
463 OES_EGL_image,
464 OES_EGL_image_external,
465 OES_EGL_sync,
466 OES_compressed_ETC1_RGB8_texture,
467 OES_depth24,
468 OES_depth32,
469 OES_depth_texture,
470 OES_draw_buffers_indexed,
471 OES_element_index_uint,
472 OES_fbo_render_mipmap,
473 OES_framebuffer_object,
474 OES_packed_depth_stencil,
475 OES_rgb8_rgba8,
476 OES_standard_derivatives,
477 OES_stencil8,
478 OES_texture_3D,
479 OES_texture_float,
480 OES_texture_float_linear,
481 OES_texture_half_float,
482 OES_texture_half_float_linear,
483 OES_texture_npot,
484 OES_vertex_array_object,
485 OVR_multiview2,
486 Extensions_Max,
487 Extensions_End
490 bool IsExtensionSupported(GLExtensions aKnownExtension) const {
491 return mAvailableExtensions[aKnownExtension];
494 protected:
495 void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
496 mAvailableExtensions[aKnownExtension] = 0;
499 void MarkExtensionSupported(GLExtensions aKnownExtension) {
500 mAvailableExtensions[aKnownExtension] = 1;
503 std::bitset<Extensions_Max> mAvailableExtensions;
505 // -----------------------------------------------------------------------------
506 // Feature queries
508 * This mecahnism introduces a new way to check if a OpenGL feature is
509 * supported, regardless of whether it is supported by an extension or
510 * natively by the context version/profile
512 public:
513 bool IsSupported(GLFeature feature) const {
514 return mAvailableFeatures[size_t(feature)];
517 static const char* GetFeatureName(GLFeature feature);
519 private:
520 std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
523 * Init features regarding OpenGL extension and context version and profile
525 void InitFeatures();
528 * Mark the feature and associated extensions as unsupported
530 void MarkUnsupported(GLFeature feature);
533 * Is this feature supported using the core (unsuffixed) symbols?
535 bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
537 // -----------------------------------------------------------------------------
538 // Error handling
540 private:
541 mutable bool mContextLost = false;
542 mutable GLenum mTopError = 0;
544 protected:
545 void OnContextLostError() const;
547 public:
548 static std::string GLErrorToString(GLenum aError);
550 static bool IsBadCallError(const GLenum err) {
551 return !(err == 0 || err == LOCAL_GL_CONTEXT_LOST);
554 class LocalErrorScope;
556 private:
557 mutable std::stack<const LocalErrorScope*> mLocalErrorScopeStack;
558 mutable UniquePtr<LocalErrorScope> mDebugErrorScope;
560 ////////////////////////////////////
561 // Use this safer option.
563 public:
564 class LocalErrorScope {
565 const GLContext& mGL;
566 GLenum mOldTop;
567 bool mHasBeenChecked;
569 public:
570 explicit LocalErrorScope(const GLContext& gl)
571 : mGL(gl), mHasBeenChecked(false) {
572 mGL.mLocalErrorScopeStack.push(this);
573 mOldTop = mGL.GetError();
576 /// Never returns CONTEXT_LOST.
577 GLenum GetError() {
578 MOZ_ASSERT(!mHasBeenChecked);
579 mHasBeenChecked = true;
581 const auto ret = mGL.GetError();
582 if (ret == LOCAL_GL_CONTEXT_LOST) return 0;
583 return ret;
586 ~LocalErrorScope() {
587 MOZ_ASSERT(mHasBeenChecked);
589 MOZ_ASSERT(!IsBadCallError(mGL.GetError()));
591 MOZ_ASSERT(mGL.mLocalErrorScopeStack.top() == this);
592 mGL.mLocalErrorScopeStack.pop();
594 mGL.mTopError = mOldTop;
598 // -
600 bool GetPotentialInteger(GLenum pname, GLint* param) {
601 LocalErrorScope localError(*this);
603 fGetIntegerv(pname, param);
605 GLenum err = localError.GetError();
606 MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_INVALID_ENUM);
607 return err == LOCAL_GL_NO_ERROR;
610 void DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
611 GLsizei length, const GLchar* message);
613 private:
614 static void GLAPIENTRY StaticDebugCallback(GLenum source, GLenum type,
615 GLuint id, GLenum severity,
616 GLsizei length,
617 const GLchar* message,
618 const GLvoid* userParam);
620 // -----------------------------------------------------------------------------
621 // Debugging implementation
622 private:
623 #ifndef MOZ_FUNCTION_NAME
624 # ifdef __GNUC__
625 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
626 # elif defined(_MSC_VER)
627 # define MOZ_FUNCTION_NAME __FUNCTION__
628 # else
629 # define MOZ_FUNCTION_NAME \
630 __func__ // defined in C99, supported in various C++ compilers. Just raw
631 // function name.
632 # endif
633 #endif
635 #ifdef MOZ_WIDGET_ANDROID
636 // Record the name of the GL call for better hang stacks on Android.
637 # define ANDROID_ONLY_PROFILER_LABEL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
638 #else
639 # define ANDROID_ONLY_PROFILER_LABEL
640 #endif
642 #define BEFORE_GL_CALL \
643 ANDROID_ONLY_PROFILER_LABEL \
644 if (MOZ_LIKELY(BeforeGLCall(MOZ_FUNCTION_NAME))) { \
645 do { \
646 } while (0)
648 #define AFTER_GL_CALL \
649 AfterGLCall(MOZ_FUNCTION_NAME); \
651 do { \
652 } while (0)
654 void BeforeGLCall_Debug(const char* funcName) const;
655 void AfterGLCall_Debug(const char* funcName) const;
656 static void OnImplicitMakeCurrentFailure(const char* funcName);
658 bool BeforeGLCall(const char* const funcName) const {
659 if (mImplicitMakeCurrent) {
660 if (MOZ_UNLIKELY(!MakeCurrent())) {
661 if (!mContextLost) {
662 OnImplicitMakeCurrentFailure(funcName);
664 return false;
667 MOZ_GL_ASSERT(this, IsCurrentImpl());
669 if (MOZ_UNLIKELY(mDebugFlags)) {
670 BeforeGLCall_Debug(funcName);
672 return true;
675 void AfterGLCall(const char* const funcName) const {
676 if (MOZ_UNLIKELY(mDebugFlags)) {
677 AfterGLCall_Debug(funcName);
681 GLContext* TrackingContext() {
682 GLContext* tip = this;
683 while (tip->mSharedContext) tip = tip->mSharedContext;
684 return tip;
687 static void AssertNotPassingStackBufferToTheGL(const void* ptr);
689 #ifdef MOZ_GL_DEBUG_BUILD
691 # define TRACKING_CONTEXT(a) \
692 do { \
693 TrackingContext()->a; \
694 } while (0)
696 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
697 AssertNotPassingStackBufferToTheGL(ptr)
699 # define ASSERT_SYMBOL_PRESENT(func) \
700 do { \
701 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, \
702 "Mismatched symbol check."); \
703 if (MOZ_UNLIKELY(!mSymbols.func)) { \
704 printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", \
705 #func); \
706 MOZ_CRASH("GFX: Uninitialized GL function"); \
708 } while (0)
710 #else // ifdef MOZ_GL_DEBUG_BUILD
712 # define TRACKING_CONTEXT(a) \
713 do { \
714 } while (0)
715 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
716 do { \
717 } while (0)
718 # define ASSERT_SYMBOL_PRESENT(func) \
719 do { \
720 } while (0)
722 #endif // ifdef MOZ_GL_DEBUG_BUILD
724 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
725 // bound.
726 void BeforeGLDrawCall() {}
728 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
729 // if it's bound.
730 void AfterGLDrawCall() { mHeavyGLCallsSinceLastFlush = true; }
732 // Do whatever setup is necessary to read from our offscreen FBO, if it's
733 // bound.
734 void BeforeGLReadCall() {}
736 // Do whatever tear-down is necessary after reading from our offscreen FBO,
737 // if it's bound.
738 void AfterGLReadCall() {}
740 public:
741 void OnSyncCall() const { mSyncGLCallCount++; }
743 uint64_t GetSyncCallCount() const { return mSyncGLCallCount; }
745 void ResetSyncCallCount(const char* resetReason) const;
747 // -----------------------------------------------------------------------------
748 // GL official entry points
749 public:
750 // We smash all errors together, so you never have to loop on this. We
751 // guarantee that immediately after this call, there are no errors left.
752 // Always returns the top-most error, except if followed by CONTEXT_LOST, then
753 // return that instead.
754 GLenum GetError() const;
756 GLenum fGetError() { return GetError(); }
758 GLenum fGetGraphicsResetStatus() const;
760 // -
762 void fActiveTexture(GLenum texture) {
763 BEFORE_GL_CALL;
764 mSymbols.fActiveTexture(texture);
765 AFTER_GL_CALL;
768 void fAttachShader(GLuint program, GLuint shader) {
769 BEFORE_GL_CALL;
770 mSymbols.fAttachShader(program, shader);
771 AFTER_GL_CALL;
774 void fBeginQuery(GLenum target, GLuint id) {
775 BEFORE_GL_CALL;
776 ASSERT_SYMBOL_PRESENT(fBeginQuery);
777 mSymbols.fBeginQuery(target, id);
778 AFTER_GL_CALL;
781 void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
782 BEFORE_GL_CALL;
783 mSymbols.fBindAttribLocation(program, index, name);
784 AFTER_GL_CALL;
787 void fBindBuffer(GLenum target, GLuint buffer) {
788 BEFORE_GL_CALL;
789 mSymbols.fBindBuffer(target, buffer);
790 AFTER_GL_CALL;
793 void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments,
794 const GLenum* attachments) {
795 BeforeGLDrawCall();
796 BEFORE_GL_CALL;
797 ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
798 mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
799 AFTER_GL_CALL;
800 AfterGLDrawCall();
803 void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
804 const GLenum* attachments, GLint x, GLint y,
805 GLsizei width, GLsizei height) {
806 BeforeGLDrawCall();
807 BEFORE_GL_CALL;
808 ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
809 mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x,
810 y, width, height);
811 AFTER_GL_CALL;
812 AfterGLDrawCall();
815 void fBindTexture(GLenum target, GLuint texture) {
816 BEFORE_GL_CALL;
817 mSymbols.fBindTexture(target, texture);
818 AFTER_GL_CALL;
821 void fBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
822 BEFORE_GL_CALL;
823 mSymbols.fBlendColor(red, green, blue, alpha);
824 AFTER_GL_CALL;
827 void fBlendEquation(GLenum mode) {
828 BEFORE_GL_CALL;
829 mSymbols.fBlendEquation(mode);
830 AFTER_GL_CALL;
833 void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
834 BEFORE_GL_CALL;
835 mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
836 AFTER_GL_CALL;
839 void fBlendFunc(GLenum sfactor, GLenum dfactor) {
840 BEFORE_GL_CALL;
841 mSymbols.fBlendFunc(sfactor, dfactor);
842 AFTER_GL_CALL;
845 void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB,
846 GLenum sfactorAlpha, GLenum dfactorAlpha) {
847 BEFORE_GL_CALL;
848 mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha,
849 dfactorAlpha);
850 AFTER_GL_CALL;
853 private:
854 void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
855 GLenum usage) {
856 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
857 BEFORE_GL_CALL;
858 mSymbols.fBufferData(target, size, data, usage);
859 OnSyncCall();
860 AFTER_GL_CALL;
861 mHeavyGLCallsSinceLastFlush = true;
864 public:
865 void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
866 GLenum usage) {
867 raw_fBufferData(target, size, data, usage);
869 // bug 744888
870 if (WorkAroundDriverBugs() && !data && Vendor() == GLVendor::NVIDIA) {
871 UniquePtr<char[]> buf = MakeUnique<char[]>(1);
872 buf[0] = 0;
873 fBufferSubData(target, size - 1, 1, buf.get());
877 void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
878 const GLvoid* data) {
879 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
880 BEFORE_GL_CALL;
881 mSymbols.fBufferSubData(target, offset, size, data);
882 AFTER_GL_CALL;
883 mHeavyGLCallsSinceLastFlush = true;
886 private:
887 void raw_fClear(GLbitfield mask) {
888 BEFORE_GL_CALL;
889 mSymbols.fClear(mask);
890 AFTER_GL_CALL;
893 public:
894 void fClear(GLbitfield mask) {
895 BeforeGLDrawCall();
896 raw_fClear(mask);
897 AfterGLDrawCall();
900 void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth,
901 GLint stencil) {
902 BeforeGLDrawCall();
903 BEFORE_GL_CALL;
904 mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
905 AFTER_GL_CALL;
906 AfterGLDrawCall();
909 void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
910 BeforeGLDrawCall();
911 BEFORE_GL_CALL;
912 mSymbols.fClearBufferfv(buffer, drawbuffer, value);
913 AFTER_GL_CALL;
914 AfterGLDrawCall();
917 void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
918 BeforeGLDrawCall();
919 BEFORE_GL_CALL;
920 mSymbols.fClearBufferiv(buffer, drawbuffer, value);
921 AFTER_GL_CALL;
922 AfterGLDrawCall();
925 void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
926 BeforeGLDrawCall();
927 BEFORE_GL_CALL;
928 mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
929 AFTER_GL_CALL;
930 AfterGLDrawCall();
933 void fClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
934 BEFORE_GL_CALL;
935 mSymbols.fClearColor(r, g, b, a);
936 AFTER_GL_CALL;
939 void fClearStencil(GLint s) {
940 BEFORE_GL_CALL;
941 mSymbols.fClearStencil(s);
942 AFTER_GL_CALL;
945 void fClientActiveTexture(GLenum texture) {
946 BEFORE_GL_CALL;
947 mSymbols.fClientActiveTexture(texture);
948 AFTER_GL_CALL;
951 void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue,
952 realGLboolean alpha) {
953 BEFORE_GL_CALL;
954 mSymbols.fColorMask(red, green, blue, alpha);
955 AFTER_GL_CALL;
958 void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
959 GLsizei width, GLsizei height, GLint border,
960 GLsizei imageSize, const GLvoid* pixels) {
961 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
962 BEFORE_GL_CALL;
963 mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height,
964 border, imageSize, pixels);
965 AFTER_GL_CALL;
966 mHeavyGLCallsSinceLastFlush = true;
969 void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
970 GLint yoffset, GLsizei width, GLsizei height,
971 GLenum format, GLsizei imageSize,
972 const GLvoid* pixels) {
973 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
974 BEFORE_GL_CALL;
975 mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
976 height, format, imageSize, pixels);
977 AFTER_GL_CALL;
978 mHeavyGLCallsSinceLastFlush = true;
981 void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
982 GLint x, GLint y, GLsizei width, GLsizei height,
983 GLint border);
985 void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
986 GLint yoffset, GLint x, GLint y, GLsizei width,
987 GLsizei height) {
988 BeforeGLReadCall();
989 raw_fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
990 height);
991 AfterGLReadCall();
994 void fCullFace(GLenum mode) {
995 BEFORE_GL_CALL;
996 mSymbols.fCullFace(mode);
997 AFTER_GL_CALL;
1000 void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
1001 BEFORE_GL_CALL;
1002 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
1003 mSymbols.fDebugMessageCallback(callback, userParam);
1004 AFTER_GL_CALL;
1007 void fDebugMessageControl(GLenum source, GLenum type, GLenum severity,
1008 GLsizei count, const GLuint* ids,
1009 realGLboolean enabled) {
1010 BEFORE_GL_CALL;
1011 ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
1012 mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
1013 AFTER_GL_CALL;
1016 void fDebugMessageInsert(GLenum source, GLenum type, GLuint id,
1017 GLenum severity, GLsizei length, const GLchar* buf) {
1018 BEFORE_GL_CALL;
1019 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
1020 mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
1021 AFTER_GL_CALL;
1024 void fDetachShader(GLuint program, GLuint shader) {
1025 BEFORE_GL_CALL;
1026 mSymbols.fDetachShader(program, shader);
1027 AFTER_GL_CALL;
1030 void fDepthFunc(GLenum func) {
1031 BEFORE_GL_CALL;
1032 mSymbols.fDepthFunc(func);
1033 AFTER_GL_CALL;
1036 void fDepthMask(realGLboolean flag) {
1037 BEFORE_GL_CALL;
1038 mSymbols.fDepthMask(flag);
1039 AFTER_GL_CALL;
1042 void fDisable(GLenum capability) {
1043 BEFORE_GL_CALL;
1044 mSymbols.fDisable(capability);
1045 AFTER_GL_CALL;
1048 void fDisableClientState(GLenum capability) {
1049 BEFORE_GL_CALL;
1050 mSymbols.fDisableClientState(capability);
1051 AFTER_GL_CALL;
1054 void fDisableVertexAttribArray(GLuint index) {
1055 BEFORE_GL_CALL;
1056 mSymbols.fDisableVertexAttribArray(index);
1057 AFTER_GL_CALL;
1060 void fDrawBuffer(GLenum mode) {
1061 BEFORE_GL_CALL;
1062 mSymbols.fDrawBuffer(mode);
1063 AFTER_GL_CALL;
1066 private:
1067 void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1068 BEFORE_GL_CALL;
1069 mSymbols.fDrawArrays(mode, first, count);
1070 AFTER_GL_CALL;
1073 void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type,
1074 const GLvoid* indices) {
1075 BEFORE_GL_CALL;
1076 mSymbols.fDrawElements(mode, count, type, indices);
1077 AFTER_GL_CALL;
1080 public:
1081 void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1082 BeforeGLDrawCall();
1083 raw_fDrawArrays(mode, first, count);
1084 AfterGLDrawCall();
1087 void fDrawElements(GLenum mode, GLsizei count, GLenum type,
1088 const GLvoid* indices) {
1089 BeforeGLDrawCall();
1090 raw_fDrawElements(mode, count, type, indices);
1091 AfterGLDrawCall();
1094 void fEnable(GLenum capability) {
1095 BEFORE_GL_CALL;
1096 mSymbols.fEnable(capability);
1097 AFTER_GL_CALL;
1100 void fEnableClientState(GLenum capability) {
1101 BEFORE_GL_CALL;
1102 mSymbols.fEnableClientState(capability);
1103 AFTER_GL_CALL;
1106 void fEnableVertexAttribArray(GLuint index) {
1107 BEFORE_GL_CALL;
1108 mSymbols.fEnableVertexAttribArray(index);
1109 AFTER_GL_CALL;
1112 void fEndQuery(GLenum target) {
1113 BEFORE_GL_CALL;
1114 ASSERT_SYMBOL_PRESENT(fEndQuery);
1115 mSymbols.fEndQuery(target);
1116 AFTER_GL_CALL;
1119 void fFinish() {
1120 BEFORE_GL_CALL;
1121 mSymbols.fFinish();
1122 OnSyncCall();
1123 AFTER_GL_CALL;
1124 mHeavyGLCallsSinceLastFlush = false;
1127 void fFlush() {
1128 BEFORE_GL_CALL;
1129 mSymbols.fFlush();
1130 AFTER_GL_CALL;
1131 mHeavyGLCallsSinceLastFlush = false;
1134 void fFrontFace(GLenum face) {
1135 BEFORE_GL_CALL;
1136 mSymbols.fFrontFace(face);
1137 AFTER_GL_CALL;
1140 void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength,
1141 GLsizei* length, GLint* size, GLenum* type,
1142 GLchar* name) {
1143 BEFORE_GL_CALL;
1144 mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type,
1145 name);
1146 OnSyncCall();
1147 AFTER_GL_CALL;
1150 void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength,
1151 GLsizei* length, GLint* size, GLenum* type,
1152 GLchar* name) {
1153 BEFORE_GL_CALL;
1154 mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type,
1155 name);
1156 OnSyncCall();
1157 AFTER_GL_CALL;
1160 void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count,
1161 GLuint* shaders) {
1162 BEFORE_GL_CALL;
1163 mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
1164 OnSyncCall();
1165 AFTER_GL_CALL;
1168 GLint fGetAttribLocation(GLuint program, const GLchar* name) {
1169 GLint retval = 0;
1170 BEFORE_GL_CALL;
1171 retval = mSymbols.fGetAttribLocation(program, name);
1172 OnSyncCall();
1173 AFTER_GL_CALL;
1174 return retval;
1177 private:
1178 void raw_fGetIntegerv(GLenum pname, GLint* params) const {
1179 BEFORE_GL_CALL;
1180 mSymbols.fGetIntegerv(pname, params);
1181 OnSyncCall();
1182 AFTER_GL_CALL;
1185 public:
1186 void fGetIntegerv(GLenum pname, GLint* params) const;
1188 template <typename T>
1189 void GetInt(const GLenum pname, T* const params) const {
1190 static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
1191 fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
1194 void GetUIntegerv(GLenum pname, GLuint* params) const {
1195 GetInt(pname, params);
1198 template <typename T>
1199 T GetIntAs(GLenum pname) const {
1200 static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
1201 T ret = 0;
1202 fGetIntegerv(pname, (GLint*)&ret);
1203 return ret;
1206 void fGetFloatv(GLenum pname, GLfloat* params) const {
1207 BEFORE_GL_CALL;
1208 mSymbols.fGetFloatv(pname, params);
1209 OnSyncCall();
1210 AFTER_GL_CALL;
1213 void fGetBooleanv(GLenum pname, realGLboolean* params) const {
1214 BEFORE_GL_CALL;
1215 mSymbols.fGetBooleanv(pname, params);
1216 OnSyncCall();
1217 AFTER_GL_CALL;
1220 void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
1221 BEFORE_GL_CALL;
1222 mSymbols.fGetBufferParameteriv(target, pname, params);
1223 OnSyncCall();
1224 AFTER_GL_CALL;
1227 GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources,
1228 GLenum* types, GLuint* ids, GLenum* severities,
1229 GLsizei* lengths, GLchar* messageLog) {
1230 GLuint ret = 0;
1231 BEFORE_GL_CALL;
1232 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
1233 ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids,
1234 severities, lengths, messageLog);
1235 OnSyncCall();
1236 AFTER_GL_CALL;
1237 return ret;
1240 void fGetPointerv(GLenum pname, GLvoid** params) {
1241 BEFORE_GL_CALL;
1242 ASSERT_SYMBOL_PRESENT(fGetPointerv);
1243 mSymbols.fGetPointerv(pname, params);
1244 OnSyncCall();
1245 AFTER_GL_CALL;
1248 void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
1249 GLsizei* length, GLchar* label) {
1250 BEFORE_GL_CALL;
1251 ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
1252 mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
1253 OnSyncCall();
1254 AFTER_GL_CALL;
1257 void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length,
1258 GLchar* label) {
1259 BEFORE_GL_CALL;
1260 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
1261 mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
1262 OnSyncCall();
1263 AFTER_GL_CALL;
1266 void fGenerateMipmap(GLenum target) {
1267 BEFORE_GL_CALL;
1268 mSymbols.fGenerateMipmap(target);
1269 AFTER_GL_CALL;
1272 void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
1273 BEFORE_GL_CALL;
1274 mSymbols.fGetProgramiv(program, pname, param);
1275 OnSyncCall();
1276 AFTER_GL_CALL;
1279 void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length,
1280 GLchar* infoLog) {
1281 BEFORE_GL_CALL;
1282 mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
1283 OnSyncCall();
1284 AFTER_GL_CALL;
1287 void fTexParameteri(GLenum target, GLenum pname, GLint param) {
1288 BEFORE_GL_CALL;
1289 mSymbols.fTexParameteri(target, pname, param);
1290 AFTER_GL_CALL;
1293 void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
1294 BEFORE_GL_CALL;
1295 mSymbols.fTexParameteriv(target, pname, params);
1296 AFTER_GL_CALL;
1299 void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
1300 BEFORE_GL_CALL;
1301 mSymbols.fTexParameterf(target, pname, param);
1302 AFTER_GL_CALL;
1305 const GLubyte* fGetString(GLenum name) {
1306 const GLubyte* result = nullptr;
1307 BEFORE_GL_CALL;
1308 result = mSymbols.fGetString(name);
1309 OnSyncCall();
1310 AFTER_GL_CALL;
1311 return result;
1314 void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
1315 GLvoid* img) {
1316 BEFORE_GL_CALL;
1317 ASSERT_SYMBOL_PRESENT(fGetTexImage);
1318 mSymbols.fGetTexImage(target, level, format, type, img);
1319 OnSyncCall();
1320 AFTER_GL_CALL;
1323 void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname,
1324 GLint* params) {
1325 BEFORE_GL_CALL;
1326 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
1327 mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
1328 OnSyncCall();
1329 AFTER_GL_CALL;
1332 void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
1333 BEFORE_GL_CALL;
1334 mSymbols.fGetTexParameterfv(target, pname, params);
1335 OnSyncCall();
1336 AFTER_GL_CALL;
1339 void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
1340 BEFORE_GL_CALL;
1341 mSymbols.fGetTexParameteriv(target, pname, params);
1342 OnSyncCall();
1343 AFTER_GL_CALL;
1346 void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
1347 BEFORE_GL_CALL;
1348 mSymbols.fGetUniformfv(program, location, params);
1349 OnSyncCall();
1350 AFTER_GL_CALL;
1353 void fGetUniformiv(GLuint program, GLint location, GLint* params) {
1354 BEFORE_GL_CALL;
1355 mSymbols.fGetUniformiv(program, location, params);
1356 OnSyncCall();
1357 AFTER_GL_CALL;
1360 void fGetUniformuiv(GLuint program, GLint location, GLuint* params) {
1361 BEFORE_GL_CALL;
1362 ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
1363 mSymbols.fGetUniformuiv(program, location, params);
1364 OnSyncCall();
1365 AFTER_GL_CALL;
1368 GLint fGetUniformLocation(GLuint programObj, const GLchar* name) {
1369 GLint retval = 0;
1370 BEFORE_GL_CALL;
1371 retval = mSymbols.fGetUniformLocation(programObj, name);
1372 OnSyncCall();
1373 AFTER_GL_CALL;
1374 return retval;
1377 void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
1378 BEFORE_GL_CALL;
1379 mSymbols.fGetVertexAttribfv(index, pname, retval);
1380 OnSyncCall();
1381 AFTER_GL_CALL;
1384 void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
1385 BEFORE_GL_CALL;
1386 mSymbols.fGetVertexAttribiv(index, pname, retval);
1387 OnSyncCall();
1388 AFTER_GL_CALL;
1391 void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
1392 BEFORE_GL_CALL;
1393 mSymbols.fGetVertexAttribPointerv(index, pname, retval);
1394 OnSyncCall();
1395 AFTER_GL_CALL;
1398 void fHint(GLenum target, GLenum mode) {
1399 BEFORE_GL_CALL;
1400 mSymbols.fHint(target, mode);
1401 AFTER_GL_CALL;
1404 realGLboolean fIsBuffer(GLuint buffer) {
1405 realGLboolean retval = false;
1406 BEFORE_GL_CALL;
1407 retval = mSymbols.fIsBuffer(buffer);
1408 OnSyncCall();
1409 AFTER_GL_CALL;
1410 return retval;
1413 realGLboolean fIsEnabled(GLenum capability) {
1414 realGLboolean retval = false;
1415 BEFORE_GL_CALL;
1416 retval = mSymbols.fIsEnabled(capability);
1417 AFTER_GL_CALL;
1418 return retval;
1421 void SetEnabled(const GLenum cap, const bool val) {
1422 if (val) {
1423 fEnable(cap);
1424 } else {
1425 fDisable(cap);
1429 bool PushEnabled(const GLenum cap, const bool newVal) {
1430 const bool oldVal = fIsEnabled(cap);
1431 if (oldVal != newVal) {
1432 SetEnabled(cap, newVal);
1434 return oldVal;
1437 realGLboolean fIsProgram(GLuint program) {
1438 realGLboolean retval = false;
1439 BEFORE_GL_CALL;
1440 retval = mSymbols.fIsProgram(program);
1441 AFTER_GL_CALL;
1442 return retval;
1445 realGLboolean fIsShader(GLuint shader) {
1446 realGLboolean retval = false;
1447 BEFORE_GL_CALL;
1448 retval = mSymbols.fIsShader(shader);
1449 AFTER_GL_CALL;
1450 return retval;
1453 realGLboolean fIsTexture(GLuint texture) {
1454 realGLboolean retval = false;
1455 BEFORE_GL_CALL;
1456 retval = mSymbols.fIsTexture(texture);
1457 AFTER_GL_CALL;
1458 return retval;
1461 void fLineWidth(GLfloat width) {
1462 BEFORE_GL_CALL;
1463 mSymbols.fLineWidth(width);
1464 AFTER_GL_CALL;
1467 void fLinkProgram(GLuint program) {
1468 BEFORE_GL_CALL;
1469 mSymbols.fLinkProgram(program);
1470 AFTER_GL_CALL;
1473 void fObjectLabel(GLenum identifier, GLuint name, GLsizei length,
1474 const GLchar* label) {
1475 BEFORE_GL_CALL;
1476 ASSERT_SYMBOL_PRESENT(fObjectLabel);
1477 mSymbols.fObjectLabel(identifier, name, length, label);
1478 AFTER_GL_CALL;
1481 void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
1482 BEFORE_GL_CALL;
1483 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
1484 mSymbols.fObjectPtrLabel(ptr, length, label);
1485 AFTER_GL_CALL;
1488 void fLoadIdentity() {
1489 BEFORE_GL_CALL;
1490 mSymbols.fLoadIdentity();
1491 AFTER_GL_CALL;
1494 void fLoadMatrixf(const GLfloat* matrix) {
1495 BEFORE_GL_CALL;
1496 mSymbols.fLoadMatrixf(matrix);
1497 AFTER_GL_CALL;
1500 void fMatrixMode(GLenum mode) {
1501 BEFORE_GL_CALL;
1502 mSymbols.fMatrixMode(mode);
1503 AFTER_GL_CALL;
1506 void fPixelStorei(GLenum pname, GLint param) {
1507 BEFORE_GL_CALL;
1508 mSymbols.fPixelStorei(pname, param);
1509 AFTER_GL_CALL;
1512 void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid* pointer) {
1513 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer);
1514 BEFORE_GL_CALL;
1515 mSymbols.fTextureRangeAPPLE(target, length, pointer);
1516 AFTER_GL_CALL;
1519 void fPointParameterf(GLenum pname, GLfloat param) {
1520 BEFORE_GL_CALL;
1521 mSymbols.fPointParameterf(pname, param);
1522 AFTER_GL_CALL;
1525 void fPolygonMode(GLenum face, GLenum mode) {
1526 BEFORE_GL_CALL;
1527 mSymbols.fPolygonMode(face, mode);
1528 AFTER_GL_CALL;
1531 void fPolygonOffset(GLfloat factor, GLfloat bias) {
1532 BEFORE_GL_CALL;
1533 mSymbols.fPolygonOffset(factor, bias);
1534 AFTER_GL_CALL;
1537 void fPopDebugGroup() {
1538 BEFORE_GL_CALL;
1539 ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
1540 mSymbols.fPopDebugGroup();
1541 AFTER_GL_CALL;
1544 void fPushDebugGroup(GLenum source, GLuint id, GLsizei length,
1545 const GLchar* message) {
1546 BEFORE_GL_CALL;
1547 ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
1548 mSymbols.fPushDebugGroup(source, id, length, message);
1549 AFTER_GL_CALL;
1552 void fReadBuffer(GLenum mode) {
1553 BEFORE_GL_CALL;
1554 mSymbols.fReadBuffer(mode);
1555 AFTER_GL_CALL;
1558 void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1559 GLenum format, GLenum type, GLvoid* pixels) {
1560 BEFORE_GL_CALL;
1561 mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
1562 OnSyncCall();
1563 AFTER_GL_CALL;
1564 mHeavyGLCallsSinceLastFlush = true;
1567 void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1568 GLenum format, GLenum type, GLvoid* pixels);
1570 public:
1571 void fSampleCoverage(GLclampf value, realGLboolean invert) {
1572 BEFORE_GL_CALL;
1573 mSymbols.fSampleCoverage(value, invert);
1574 AFTER_GL_CALL;
1577 void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1578 if (mScissorRect[0] == x && mScissorRect[1] == y &&
1579 mScissorRect[2] == width && mScissorRect[3] == height) {
1580 return;
1582 mScissorRect[0] = x;
1583 mScissorRect[1] = y;
1584 mScissorRect[2] = width;
1585 mScissorRect[3] = height;
1586 BEFORE_GL_CALL;
1587 mSymbols.fScissor(x, y, width, height);
1588 AFTER_GL_CALL;
1591 void fStencilFunc(GLenum func, GLint reference, GLuint mask) {
1592 BEFORE_GL_CALL;
1593 mSymbols.fStencilFunc(func, reference, mask);
1594 AFTER_GL_CALL;
1597 void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint reference,
1598 GLuint mask) {
1599 BEFORE_GL_CALL;
1600 mSymbols.fStencilFuncSeparate(frontfunc, backfunc, reference, mask);
1601 AFTER_GL_CALL;
1604 void fStencilMask(GLuint mask) {
1605 BEFORE_GL_CALL;
1606 mSymbols.fStencilMask(mask);
1607 AFTER_GL_CALL;
1610 void fStencilMaskSeparate(GLenum face, GLuint mask) {
1611 BEFORE_GL_CALL;
1612 mSymbols.fStencilMaskSeparate(face, mask);
1613 AFTER_GL_CALL;
1616 void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
1617 BEFORE_GL_CALL;
1618 mSymbols.fStencilOp(fail, zfail, zpass);
1619 AFTER_GL_CALL;
1622 void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
1623 GLenum dppass) {
1624 BEFORE_GL_CALL;
1625 mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
1626 AFTER_GL_CALL;
1629 void fTexGeni(GLenum coord, GLenum pname, GLint param) {
1630 BEFORE_GL_CALL;
1631 mSymbols.fTexGeni(coord, pname, param);
1632 AFTER_GL_CALL;
1635 void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
1636 BEFORE_GL_CALL;
1637 mSymbols.fTexGenf(coord, pname, param);
1638 AFTER_GL_CALL;
1641 void fTexGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1642 BEFORE_GL_CALL;
1643 mSymbols.fTexGenfv(coord, pname, params);
1644 AFTER_GL_CALL;
1647 private:
1648 void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat,
1649 GLsizei width, GLsizei height, GLint border,
1650 GLenum format, GLenum type, const GLvoid* pixels) {
1651 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1652 BEFORE_GL_CALL;
1653 mSymbols.fTexImage2D(target, level, internalformat, width, height, border,
1654 format, type, pixels);
1655 AFTER_GL_CALL;
1656 mHeavyGLCallsSinceLastFlush = true;
1659 public:
1660 void fTexImage2D(GLenum target, GLint level, GLint internalformat,
1661 GLsizei width, GLsizei height, GLint border, GLenum format,
1662 GLenum type, const GLvoid* pixels);
1664 void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
1665 GLsizei width, GLsizei height, GLenum format, GLenum type,
1666 const GLvoid* pixels) {
1667 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1668 BEFORE_GL_CALL;
1669 mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height,
1670 format, type, pixels);
1671 AFTER_GL_CALL;
1672 mHeavyGLCallsSinceLastFlush = true;
1675 void fUniform1f(GLint location, GLfloat v0) {
1676 BEFORE_GL_CALL;
1677 mSymbols.fUniform1f(location, v0);
1678 AFTER_GL_CALL;
1681 void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
1682 BEFORE_GL_CALL;
1683 mSymbols.fUniform1fv(location, count, value);
1684 AFTER_GL_CALL;
1687 void fUniform1i(GLint location, GLint v0) {
1688 BEFORE_GL_CALL;
1689 mSymbols.fUniform1i(location, v0);
1690 AFTER_GL_CALL;
1693 void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
1694 BEFORE_GL_CALL;
1695 mSymbols.fUniform1iv(location, count, value);
1696 AFTER_GL_CALL;
1699 void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
1700 BEFORE_GL_CALL;
1701 mSymbols.fUniform2f(location, v0, v1);
1702 AFTER_GL_CALL;
1705 void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
1706 BEFORE_GL_CALL;
1707 mSymbols.fUniform2fv(location, count, value);
1708 AFTER_GL_CALL;
1711 void fUniform2i(GLint location, GLint v0, GLint v1) {
1712 BEFORE_GL_CALL;
1713 mSymbols.fUniform2i(location, v0, v1);
1714 AFTER_GL_CALL;
1717 void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
1718 BEFORE_GL_CALL;
1719 mSymbols.fUniform2iv(location, count, value);
1720 AFTER_GL_CALL;
1723 void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
1724 BEFORE_GL_CALL;
1725 mSymbols.fUniform3f(location, v0, v1, v2);
1726 AFTER_GL_CALL;
1729 void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
1730 BEFORE_GL_CALL;
1731 mSymbols.fUniform3fv(location, count, value);
1732 AFTER_GL_CALL;
1735 void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
1736 BEFORE_GL_CALL;
1737 mSymbols.fUniform3i(location, v0, v1, v2);
1738 AFTER_GL_CALL;
1741 void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
1742 BEFORE_GL_CALL;
1743 mSymbols.fUniform3iv(location, count, value);
1744 AFTER_GL_CALL;
1747 void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
1748 GLfloat v3) {
1749 BEFORE_GL_CALL;
1750 mSymbols.fUniform4f(location, v0, v1, v2, v3);
1751 AFTER_GL_CALL;
1754 void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
1755 BEFORE_GL_CALL;
1756 mSymbols.fUniform4fv(location, count, value);
1757 AFTER_GL_CALL;
1760 void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
1761 BEFORE_GL_CALL;
1762 mSymbols.fUniform4i(location, v0, v1, v2, v3);
1763 AFTER_GL_CALL;
1766 void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
1767 BEFORE_GL_CALL;
1768 mSymbols.fUniform4iv(location, count, value);
1769 AFTER_GL_CALL;
1772 void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose,
1773 const GLfloat* value) {
1774 BEFORE_GL_CALL;
1775 mSymbols.fUniformMatrix2fv(location, count, transpose, value);
1776 AFTER_GL_CALL;
1779 void fUniformMatrix2x3fv(GLint location, GLsizei count,
1780 realGLboolean transpose, const GLfloat* value) {
1781 BEFORE_GL_CALL;
1782 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv);
1783 mSymbols.fUniformMatrix2x3fv(location, count, transpose, value);
1784 AFTER_GL_CALL;
1787 void fUniformMatrix2x4fv(GLint location, GLsizei count,
1788 realGLboolean transpose, const GLfloat* value) {
1789 BEFORE_GL_CALL;
1790 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv);
1791 mSymbols.fUniformMatrix2x4fv(location, count, transpose, value);
1792 AFTER_GL_CALL;
1795 void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose,
1796 const GLfloat* value) {
1797 BEFORE_GL_CALL;
1798 mSymbols.fUniformMatrix3fv(location, count, transpose, value);
1799 AFTER_GL_CALL;
1802 void fUniformMatrix3x2fv(GLint location, GLsizei count,
1803 realGLboolean transpose, const GLfloat* value) {
1804 BEFORE_GL_CALL;
1805 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv);
1806 mSymbols.fUniformMatrix3x2fv(location, count, transpose, value);
1807 AFTER_GL_CALL;
1810 void fUniformMatrix3x4fv(GLint location, GLsizei count,
1811 realGLboolean transpose, const GLfloat* value) {
1812 BEFORE_GL_CALL;
1813 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv);
1814 mSymbols.fUniformMatrix3x4fv(location, count, transpose, value);
1815 AFTER_GL_CALL;
1818 void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose,
1819 const GLfloat* value) {
1820 BEFORE_GL_CALL;
1821 mSymbols.fUniformMatrix4fv(location, count, transpose, value);
1822 AFTER_GL_CALL;
1825 void fUniformMatrix4x2fv(GLint location, GLsizei count,
1826 realGLboolean transpose, const GLfloat* value) {
1827 BEFORE_GL_CALL;
1828 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv);
1829 mSymbols.fUniformMatrix4x2fv(location, count, transpose, value);
1830 AFTER_GL_CALL;
1833 void fUniformMatrix4x3fv(GLint location, GLsizei count,
1834 realGLboolean transpose, const GLfloat* value) {
1835 BEFORE_GL_CALL;
1836 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv);
1837 mSymbols.fUniformMatrix4x3fv(location, count, transpose, value);
1838 AFTER_GL_CALL;
1841 void fUseProgram(GLuint program) {
1842 BEFORE_GL_CALL;
1843 mSymbols.fUseProgram(program);
1844 AFTER_GL_CALL;
1847 void fValidateProgram(GLuint program) {
1848 BEFORE_GL_CALL;
1849 mSymbols.fValidateProgram(program);
1850 AFTER_GL_CALL;
1853 void fVertexAttribPointer(GLuint index, GLint size, GLenum type,
1854 realGLboolean normalized, GLsizei stride,
1855 const GLvoid* pointer) {
1856 BEFORE_GL_CALL;
1857 mSymbols.fVertexAttribPointer(index, size, type, normalized, stride,
1858 pointer);
1859 AFTER_GL_CALL;
1862 void fVertexAttrib1f(GLuint index, GLfloat x) {
1863 BEFORE_GL_CALL;
1864 mSymbols.fVertexAttrib1f(index, x);
1865 AFTER_GL_CALL;
1868 void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1869 BEFORE_GL_CALL;
1870 mSymbols.fVertexAttrib2f(index, x, y);
1871 AFTER_GL_CALL;
1874 void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1875 BEFORE_GL_CALL;
1876 mSymbols.fVertexAttrib3f(index, x, y, z);
1877 AFTER_GL_CALL;
1880 void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z,
1881 GLfloat w) {
1882 BEFORE_GL_CALL;
1883 mSymbols.fVertexAttrib4f(index, x, y, z, w);
1884 AFTER_GL_CALL;
1887 void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
1888 BEFORE_GL_CALL;
1889 mSymbols.fVertexAttrib1fv(index, v);
1890 AFTER_GL_CALL;
1893 void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
1894 BEFORE_GL_CALL;
1895 mSymbols.fVertexAttrib2fv(index, v);
1896 AFTER_GL_CALL;
1899 void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
1900 BEFORE_GL_CALL;
1901 mSymbols.fVertexAttrib3fv(index, v);
1902 AFTER_GL_CALL;
1905 void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
1906 BEFORE_GL_CALL;
1907 mSymbols.fVertexAttrib4fv(index, v);
1908 AFTER_GL_CALL;
1911 void fVertexPointer(GLint size, GLenum type, GLsizei stride,
1912 const GLvoid* pointer) {
1913 BEFORE_GL_CALL;
1914 mSymbols.fVertexPointer(size, type, stride, pointer);
1915 AFTER_GL_CALL;
1918 void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
1919 if (mViewportRect[0] == x && mViewportRect[1] == y &&
1920 mViewportRect[2] == width && mViewportRect[3] == height) {
1921 return;
1923 mViewportRect[0] = x;
1924 mViewportRect[1] = y;
1925 mViewportRect[2] = width;
1926 mViewportRect[3] = height;
1927 BEFORE_GL_CALL;
1928 mSymbols.fViewport(x, y, width, height);
1929 AFTER_GL_CALL;
1932 void fCompileShader(GLuint shader) {
1933 BEFORE_GL_CALL;
1934 mSymbols.fCompileShader(shader);
1935 AFTER_GL_CALL;
1938 private:
1939 friend class SharedSurface_IOSurface;
1941 void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
1942 GLint x, GLint y, GLsizei width, GLsizei height,
1943 GLint border) {
1944 BEFORE_GL_CALL;
1945 mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height,
1946 border);
1947 AFTER_GL_CALL;
1950 void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
1951 GLint yoffset, GLint x, GLint y, GLsizei width,
1952 GLsizei height) {
1953 BEFORE_GL_CALL;
1954 mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
1955 height);
1956 AFTER_GL_CALL;
1959 public:
1960 void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
1961 BEFORE_GL_CALL;
1962 mSymbols.fGetShaderiv(shader, pname, param);
1963 OnSyncCall();
1964 AFTER_GL_CALL;
1967 void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length,
1968 GLchar* infoLog) {
1969 BEFORE_GL_CALL;
1970 mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
1971 OnSyncCall();
1972 AFTER_GL_CALL;
1975 private:
1976 void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1977 GLint* range, GLint* precision) {
1978 MOZ_ASSERT(IsGLES());
1980 BEFORE_GL_CALL;
1981 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
1982 mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range,
1983 precision);
1984 OnSyncCall();
1985 AFTER_GL_CALL;
1988 public:
1989 void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1990 GLint* range, GLint* precision) {
1991 if (IsGLES()) {
1992 raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range,
1993 precision);
1994 } else {
1995 // Fall back to automatic values because almost all desktop hardware
1996 // supports the OpenGL standard precisions.
1997 GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range,
1998 precision);
2002 void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length,
2003 GLchar* source) {
2004 BEFORE_GL_CALL;
2005 mSymbols.fGetShaderSource(obj, maxLength, length, source);
2006 OnSyncCall();
2007 AFTER_GL_CALL;
2010 void fShaderSource(GLuint shader, GLsizei count, const GLchar* const* strings,
2011 const GLint* lengths) {
2012 BEFORE_GL_CALL;
2013 mSymbols.fShaderSource(shader, count, strings, lengths);
2014 AFTER_GL_CALL;
2017 private:
2018 mutable GLuint mCachedDrawFb = 0;
2019 mutable GLuint mCachedReadFb = 0;
2021 public:
2022 bool mElideDuplicateBindFramebuffers = false;
2024 void fBindFramebuffer(const GLenum target, const GLuint fb) const {
2025 if (mElideDuplicateBindFramebuffers) {
2026 MOZ_ASSERT(mCachedDrawFb ==
2027 GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING));
2028 MOZ_ASSERT(mCachedReadFb ==
2029 GetIntAs<GLuint>(LOCAL_GL_READ_FRAMEBUFFER_BINDING));
2031 switch (target) {
2032 case LOCAL_GL_FRAMEBUFFER:
2033 if (mCachedDrawFb == fb && mCachedReadFb == fb) return;
2034 break;
2035 case LOCAL_GL_DRAW_FRAMEBUFFER:
2036 if (mCachedDrawFb == fb) return;
2037 break;
2038 case LOCAL_GL_READ_FRAMEBUFFER:
2039 if (mCachedReadFb == fb) return;
2040 break;
2044 BEFORE_GL_CALL;
2045 mSymbols.fBindFramebuffer(target, fb);
2046 AFTER_GL_CALL;
2048 switch (target) {
2049 case LOCAL_GL_FRAMEBUFFER:
2050 mCachedDrawFb = fb;
2051 mCachedReadFb = fb;
2052 break;
2053 case LOCAL_GL_DRAW_FRAMEBUFFER:
2054 mCachedDrawFb = fb;
2055 break;
2056 case LOCAL_GL_READ_FRAMEBUFFER:
2057 mCachedReadFb = fb;
2058 break;
2062 void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
2063 BEFORE_GL_CALL;
2064 mSymbols.fBindRenderbuffer(target, renderbuffer);
2065 AFTER_GL_CALL;
2068 GLenum fCheckFramebufferStatus(GLenum target) {
2069 GLenum retval = 0;
2070 BEFORE_GL_CALL;
2071 retval = mSymbols.fCheckFramebufferStatus(target);
2072 OnSyncCall();
2073 AFTER_GL_CALL;
2074 return retval;
2077 void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint,
2078 GLenum renderbufferTarget,
2079 GLuint renderbuffer) {
2080 BEFORE_GL_CALL;
2081 mSymbols.fFramebufferRenderbuffer(target, attachmentPoint,
2082 renderbufferTarget, renderbuffer);
2083 AFTER_GL_CALL;
2086 void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint,
2087 GLenum textureTarget, GLuint texture,
2088 GLint level) {
2089 BEFORE_GL_CALL;
2090 mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget,
2091 texture, level);
2092 AFTER_GL_CALL;
2093 if (mNeedsCheckAfterAttachTextureToFb) {
2094 fCheckFramebufferStatus(target);
2098 void fFramebufferTextureLayer(GLenum target, GLenum attachment,
2099 GLuint texture, GLint level, GLint layer) {
2100 BEFORE_GL_CALL;
2101 ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
2102 mSymbols.fFramebufferTextureLayer(target, attachment, texture, level,
2103 layer);
2104 AFTER_GL_CALL;
2107 void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
2108 GLenum pname, GLint* value) {
2109 BEFORE_GL_CALL;
2110 mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname,
2111 value);
2112 OnSyncCall();
2113 AFTER_GL_CALL;
2116 void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
2117 BEFORE_GL_CALL;
2118 mSymbols.fGetRenderbufferParameteriv(target, pname, value);
2119 OnSyncCall();
2120 AFTER_GL_CALL;
2123 realGLboolean fIsFramebuffer(GLuint framebuffer) {
2124 realGLboolean retval = false;
2125 BEFORE_GL_CALL;
2126 retval = mSymbols.fIsFramebuffer(framebuffer);
2127 OnSyncCall();
2128 AFTER_GL_CALL;
2129 return retval;
2132 public:
2133 realGLboolean fIsRenderbuffer(GLuint renderbuffer) {
2134 realGLboolean retval = false;
2135 BEFORE_GL_CALL;
2136 retval = mSymbols.fIsRenderbuffer(renderbuffer);
2137 OnSyncCall();
2138 AFTER_GL_CALL;
2139 return retval;
2142 void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width,
2143 GLsizei height) {
2144 BEFORE_GL_CALL;
2145 mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
2146 AFTER_GL_CALL;
2149 private:
2150 void raw_fDepthRange(GLclampf a, GLclampf b) {
2151 MOZ_ASSERT(!IsGLES());
2153 BEFORE_GL_CALL;
2154 ASSERT_SYMBOL_PRESENT(fDepthRange);
2155 mSymbols.fDepthRange(a, b);
2156 AFTER_GL_CALL;
2159 void raw_fDepthRangef(GLclampf a, GLclampf b) {
2160 MOZ_ASSERT(IsGLES());
2162 BEFORE_GL_CALL;
2163 ASSERT_SYMBOL_PRESENT(fDepthRangef);
2164 mSymbols.fDepthRangef(a, b);
2165 AFTER_GL_CALL;
2168 void raw_fClearDepth(GLclampf v) {
2169 MOZ_ASSERT(!IsGLES());
2171 BEFORE_GL_CALL;
2172 ASSERT_SYMBOL_PRESENT(fClearDepth);
2173 mSymbols.fClearDepth(v);
2174 AFTER_GL_CALL;
2177 void raw_fClearDepthf(GLclampf v) {
2178 MOZ_ASSERT(IsGLES());
2180 BEFORE_GL_CALL;
2181 ASSERT_SYMBOL_PRESENT(fClearDepthf);
2182 mSymbols.fClearDepthf(v);
2183 AFTER_GL_CALL;
2186 public:
2187 void fDepthRange(GLclampf a, GLclampf b) {
2188 if (IsGLES()) {
2189 raw_fDepthRangef(a, b);
2190 } else {
2191 raw_fDepthRange(a, b);
2195 void fClearDepth(GLclampf v) {
2196 if (IsGLES()) {
2197 raw_fClearDepthf(v);
2198 } else {
2199 raw_fClearDepth(v);
2203 void* fMapBuffer(GLenum target, GLenum access) {
2204 void* ret = nullptr;
2205 BEFORE_GL_CALL;
2206 ASSERT_SYMBOL_PRESENT(fMapBuffer);
2207 ret = mSymbols.fMapBuffer(target, access);
2208 OnSyncCall();
2209 AFTER_GL_CALL;
2210 return ret;
2213 realGLboolean fUnmapBuffer(GLenum target) {
2214 realGLboolean ret = false;
2215 BEFORE_GL_CALL;
2216 ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
2217 ret = mSymbols.fUnmapBuffer(target);
2218 AFTER_GL_CALL;
2219 return ret;
2222 private:
2223 GLuint raw_fCreateProgram() {
2224 GLuint ret = 0;
2225 BEFORE_GL_CALL;
2226 ret = mSymbols.fCreateProgram();
2227 AFTER_GL_CALL;
2228 return ret;
2231 GLuint raw_fCreateShader(GLenum t) {
2232 GLuint ret = 0;
2233 BEFORE_GL_CALL;
2234 ret = mSymbols.fCreateShader(t);
2235 AFTER_GL_CALL;
2236 return ret;
2239 void raw_fGenBuffers(GLsizei n, GLuint* names) {
2240 BEFORE_GL_CALL;
2241 mSymbols.fGenBuffers(n, names);
2242 OnSyncCall();
2243 AFTER_GL_CALL;
2246 void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
2247 BEFORE_GL_CALL;
2248 mSymbols.fGenFramebuffers(n, names);
2249 OnSyncCall();
2250 AFTER_GL_CALL;
2253 void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
2254 BEFORE_GL_CALL;
2255 mSymbols.fGenRenderbuffers(n, names);
2256 OnSyncCall();
2257 AFTER_GL_CALL;
2260 void raw_fGenTextures(GLsizei n, GLuint* names) {
2261 BEFORE_GL_CALL;
2262 mSymbols.fGenTextures(n, names);
2263 OnSyncCall();
2264 AFTER_GL_CALL;
2267 public:
2268 GLuint fCreateProgram() {
2269 GLuint ret = raw_fCreateProgram();
2270 TRACKING_CONTEXT(CreatedProgram(this, ret));
2271 return ret;
2274 GLuint fCreateShader(GLenum t) {
2275 GLuint ret = raw_fCreateShader(t);
2276 TRACKING_CONTEXT(CreatedShader(this, ret));
2277 return ret;
2280 void fGenBuffers(GLsizei n, GLuint* names) {
2281 raw_fGenBuffers(n, names);
2282 TRACKING_CONTEXT(CreatedBuffers(this, n, names));
2285 void fGenFramebuffers(GLsizei n, GLuint* names) {
2286 raw_fGenFramebuffers(n, names);
2287 TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
2290 void fGenRenderbuffers(GLsizei n, GLuint* names) {
2291 raw_fGenRenderbuffers(n, names);
2292 TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
2295 void fGenTextures(GLsizei n, GLuint* names) {
2296 raw_fGenTextures(n, names);
2297 TRACKING_CONTEXT(CreatedTextures(this, n, names));
2300 private:
2301 void raw_fDeleteProgram(GLuint program) {
2302 BEFORE_GL_CALL;
2303 mSymbols.fDeleteProgram(program);
2304 AFTER_GL_CALL;
2307 void raw_fDeleteShader(GLuint shader) {
2308 BEFORE_GL_CALL;
2309 mSymbols.fDeleteShader(shader);
2310 AFTER_GL_CALL;
2313 void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
2314 BEFORE_GL_CALL;
2315 mSymbols.fDeleteBuffers(n, names);
2316 AFTER_GL_CALL;
2319 void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2320 BEFORE_GL_CALL;
2321 mSymbols.fDeleteFramebuffers(n, names);
2322 AFTER_GL_CALL;
2324 for (const auto i : IntegerRange(n)) {
2325 const auto fb = names[i];
2326 if (mCachedDrawFb == fb) {
2327 mCachedDrawFb = 0;
2329 if (mCachedReadFb == fb) {
2330 mCachedReadFb = 0;
2335 void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2336 BEFORE_GL_CALL;
2337 mSymbols.fDeleteRenderbuffers(n, names);
2338 AFTER_GL_CALL;
2341 void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
2342 BEFORE_GL_CALL;
2343 mSymbols.fDeleteTextures(n, names);
2344 AFTER_GL_CALL;
2347 public:
2348 void fDeleteProgram(GLuint program) {
2349 raw_fDeleteProgram(program);
2350 TRACKING_CONTEXT(DeletedProgram(this, program));
2353 void fDeleteShader(GLuint shader) {
2354 raw_fDeleteShader(shader);
2355 TRACKING_CONTEXT(DeletedShader(this, shader));
2358 void fDeleteBuffers(GLsizei n, const GLuint* names) {
2359 raw_fDeleteBuffers(n, names);
2360 TRACKING_CONTEXT(DeletedBuffers(this, n, names));
2363 void fDeleteFramebuffers(GLsizei n, const GLuint* names);
2365 void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2366 raw_fDeleteRenderbuffers(n, names);
2367 TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
2370 void fDeleteTextures(GLsizei n, const GLuint* names) {
2371 #ifdef XP_MACOSX
2372 // On the Mac the call to fDeleteTextures() triggers a flush. But it
2373 // happens at the wrong time, which can lead to crashes. To work around
2374 // this we call fFlush() explicitly ourselves, before the call to
2375 // fDeleteTextures(). This fixes bug 1666293.
2376 fFlush();
2377 #endif
2378 raw_fDeleteTextures(n, names);
2379 TRACKING_CONTEXT(DeletedTextures(this, n, names));
2382 // -----------------------------------------------------------------------------
2383 // Extension ARB_sync (GL)
2384 public:
2385 GLsync fFenceSync(GLenum condition, GLbitfield flags) {
2386 GLsync ret = 0;
2387 BEFORE_GL_CALL;
2388 ASSERT_SYMBOL_PRESENT(fFenceSync);
2389 ret = mSymbols.fFenceSync(condition, flags);
2390 OnSyncCall();
2391 AFTER_GL_CALL;
2392 return ret;
2395 realGLboolean fIsSync(GLsync sync) {
2396 realGLboolean ret = false;
2397 BEFORE_GL_CALL;
2398 ASSERT_SYMBOL_PRESENT(fIsSync);
2399 ret = mSymbols.fIsSync(sync);
2400 OnSyncCall();
2401 AFTER_GL_CALL;
2402 return ret;
2405 void fDeleteSync(GLsync sync) {
2406 BEFORE_GL_CALL;
2407 ASSERT_SYMBOL_PRESENT(fDeleteSync);
2408 mSymbols.fDeleteSync(sync);
2409 AFTER_GL_CALL;
2412 GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2413 GLenum ret = 0;
2414 BEFORE_GL_CALL;
2415 ASSERT_SYMBOL_PRESENT(fClientWaitSync);
2416 ret = mSymbols.fClientWaitSync(sync, flags, timeout);
2417 OnSyncCall();
2418 AFTER_GL_CALL;
2419 return ret;
2422 void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2423 BEFORE_GL_CALL;
2424 ASSERT_SYMBOL_PRESENT(fWaitSync);
2425 mSymbols.fWaitSync(sync, flags, timeout);
2426 AFTER_GL_CALL;
2429 void fGetInteger64v(GLenum pname, GLint64* params) {
2430 BEFORE_GL_CALL;
2431 ASSERT_SYMBOL_PRESENT(fGetInteger64v);
2432 mSymbols.fGetInteger64v(pname, params);
2433 AFTER_GL_CALL;
2436 void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,
2437 GLint* values) {
2438 BEFORE_GL_CALL;
2439 ASSERT_SYMBOL_PRESENT(fGetSynciv);
2440 mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
2441 OnSyncCall();
2442 AFTER_GL_CALL;
2445 // -----------------------------------------------------------------------------
2446 // Extension OES_EGL_image (GLES)
2447 public:
2448 void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
2449 BEFORE_GL_CALL;
2450 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
2451 mSymbols.fEGLImageTargetTexture2D(target, image);
2452 AFTER_GL_CALL;
2453 mHeavyGLCallsSinceLastFlush = true;
2456 void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image) {
2457 BEFORE_GL_CALL;
2458 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
2459 mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
2460 AFTER_GL_CALL;
2463 // -----------------------------------------------------------------------------
2464 // Package XXX_bind_buffer_offset
2465 public:
2466 void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer,
2467 GLintptr offset) {
2468 BEFORE_GL_CALL;
2469 ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
2470 mSymbols.fBindBufferOffset(target, index, buffer, offset);
2471 AFTER_GL_CALL;
2474 // -----------------------------------------------------------------------------
2475 // Package XXX_draw_buffers
2476 public:
2477 void fDrawBuffers(GLsizei n, const GLenum* bufs) {
2478 BEFORE_GL_CALL;
2479 ASSERT_SYMBOL_PRESENT(fDrawBuffers);
2480 mSymbols.fDrawBuffers(n, bufs);
2481 AFTER_GL_CALL;
2484 // -----------------------------------------------------------------------------
2485 // Package XXX_draw_instanced
2486 public:
2487 void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2488 GLsizei primcount) {
2489 BeforeGLDrawCall();
2490 raw_fDrawArraysInstanced(mode, first, count, primcount);
2491 AfterGLDrawCall();
2494 void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
2495 const GLvoid* indices, GLsizei primcount) {
2496 BeforeGLDrawCall();
2497 raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
2498 AfterGLDrawCall();
2501 private:
2502 void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2503 GLsizei primcount) {
2504 BEFORE_GL_CALL;
2505 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
2506 mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
2507 AFTER_GL_CALL;
2510 void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
2511 const GLvoid* indices, GLsizei primcount) {
2512 BEFORE_GL_CALL;
2513 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
2514 mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
2515 AFTER_GL_CALL;
2518 // -----------------------------------------------------------------------------
2519 // Package XXX_framebuffer_blit
2520 public:
2521 // Draw/Read
2522 void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2523 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2524 GLbitfield mask, GLenum filter) {
2525 BeforeGLDrawCall();
2526 BeforeGLReadCall();
2527 raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
2528 mask, filter);
2529 AfterGLReadCall();
2530 AfterGLDrawCall();
2533 private:
2534 void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2535 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2536 GLbitfield mask, GLenum filter) {
2537 BEFORE_GL_CALL;
2538 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
2539 mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
2540 dstY1, mask, filter);
2541 AFTER_GL_CALL;
2544 // -----------------------------------------------------------------------------
2545 // Package XXX_framebuffer_multisample
2546 public:
2547 void fRenderbufferStorageMultisample(GLenum target, GLsizei samples,
2548 GLenum internalFormat, GLsizei width,
2549 GLsizei height) {
2550 BEFORE_GL_CALL;
2551 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
2552 mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat,
2553 width, height);
2554 AFTER_GL_CALL;
2557 // -----------------------------------------------------------------------------
2558 // GL 3.0, GL ES 3.0 & EXT_gpu_shader4
2559 public:
2560 void fGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) {
2561 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv);
2562 BEFORE_GL_CALL;
2563 mSymbols.fGetVertexAttribIiv(index, pname, params);
2564 OnSyncCall();
2565 AFTER_GL_CALL;
2568 void fGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) {
2569 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv);
2570 BEFORE_GL_CALL;
2571 mSymbols.fGetVertexAttribIuiv(index, pname, params);
2572 OnSyncCall();
2573 AFTER_GL_CALL;
2576 void fVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) {
2577 BEFORE_GL_CALL;
2578 ASSERT_SYMBOL_PRESENT(fVertexAttribI4i);
2579 mSymbols.fVertexAttribI4i(index, x, y, z, w);
2580 AFTER_GL_CALL;
2583 void fVertexAttribI4iv(GLuint index, const GLint* v) {
2584 BEFORE_GL_CALL;
2585 ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv);
2586 mSymbols.fVertexAttribI4iv(index, v);
2587 AFTER_GL_CALL;
2590 void fVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {
2591 BEFORE_GL_CALL;
2592 ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui);
2593 mSymbols.fVertexAttribI4ui(index, x, y, z, w);
2594 AFTER_GL_CALL;
2597 void fVertexAttribI4uiv(GLuint index, const GLuint* v) {
2598 BEFORE_GL_CALL;
2599 ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv);
2600 mSymbols.fVertexAttribI4uiv(index, v);
2601 AFTER_GL_CALL;
2604 void fVertexAttribIPointer(GLuint index, GLint size, GLenum type,
2605 GLsizei stride, const GLvoid* offset) {
2606 BEFORE_GL_CALL;
2607 ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer);
2608 mSymbols.fVertexAttribIPointer(index, size, type, stride, offset);
2609 AFTER_GL_CALL;
2612 void fUniform1ui(GLint location, GLuint v0) {
2613 BEFORE_GL_CALL;
2614 ASSERT_SYMBOL_PRESENT(fUniform1ui);
2615 mSymbols.fUniform1ui(location, v0);
2616 AFTER_GL_CALL;
2619 void fUniform2ui(GLint location, GLuint v0, GLuint v1) {
2620 BEFORE_GL_CALL;
2621 ASSERT_SYMBOL_PRESENT(fUniform2ui);
2622 mSymbols.fUniform2ui(location, v0, v1);
2623 AFTER_GL_CALL;
2626 void fUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {
2627 BEFORE_GL_CALL;
2628 ASSERT_SYMBOL_PRESENT(fUniform3ui);
2629 mSymbols.fUniform3ui(location, v0, v1, v2);
2630 AFTER_GL_CALL;
2633 void fUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
2634 BEFORE_GL_CALL;
2635 ASSERT_SYMBOL_PRESENT(fUniform4ui);
2636 mSymbols.fUniform4ui(location, v0, v1, v2, v3);
2637 AFTER_GL_CALL;
2640 void fUniform1uiv(GLint location, GLsizei count, const GLuint* value) {
2641 BEFORE_GL_CALL;
2642 ASSERT_SYMBOL_PRESENT(fUniform1uiv);
2643 mSymbols.fUniform1uiv(location, count, value);
2644 AFTER_GL_CALL;
2647 void fUniform2uiv(GLint location, GLsizei count, const GLuint* value) {
2648 BEFORE_GL_CALL;
2649 ASSERT_SYMBOL_PRESENT(fUniform2uiv);
2650 mSymbols.fUniform2uiv(location, count, value);
2651 AFTER_GL_CALL;
2654 void fUniform3uiv(GLint location, GLsizei count, const GLuint* value) {
2655 BEFORE_GL_CALL;
2656 ASSERT_SYMBOL_PRESENT(fUniform3uiv);
2657 mSymbols.fUniform3uiv(location, count, value);
2658 AFTER_GL_CALL;
2661 void fUniform4uiv(GLint location, GLsizei count, const GLuint* value) {
2662 BEFORE_GL_CALL;
2663 ASSERT_SYMBOL_PRESENT(fUniform4uiv);
2664 mSymbols.fUniform4uiv(location, count, value);
2665 AFTER_GL_CALL;
2668 GLint fGetFragDataLocation(GLuint program, const GLchar* name) {
2669 GLint result = 0;
2670 BEFORE_GL_CALL;
2671 ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
2672 result = mSymbols.fGetFragDataLocation(program, name);
2673 OnSyncCall();
2674 AFTER_GL_CALL;
2675 return result;
2678 // -----------------------------------------------------------------------------
2679 // Package XXX_instanced_arrays
2680 public:
2681 void fVertexAttribDivisor(GLuint index, GLuint divisor) {
2682 BEFORE_GL_CALL;
2683 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
2684 mSymbols.fVertexAttribDivisor(index, divisor);
2685 AFTER_GL_CALL;
2688 // -----------------------------------------------------------------------------
2689 // Feature internalformat_query
2690 public:
2691 void fGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
2692 GLsizei bufSize, GLint* params) {
2693 BEFORE_GL_CALL;
2694 ASSERT_SYMBOL_PRESENT(fGetInternalformativ);
2695 mSymbols.fGetInternalformativ(target, internalformat, pname, bufSize,
2696 params);
2697 OnSyncCall();
2698 AFTER_GL_CALL;
2701 // -----------------------------------------------------------------------------
2702 // Package XXX_query_counter
2704 * XXX_query_counter:
2705 * - depends on XXX_query_objects
2706 * - provide all followed entry points
2707 * - provide GL_TIMESTAMP
2709 public:
2710 void fQueryCounter(GLuint id, GLenum target) {
2711 BEFORE_GL_CALL;
2712 ASSERT_SYMBOL_PRESENT(fQueryCounter);
2713 mSymbols.fQueryCounter(id, target);
2714 AFTER_GL_CALL;
2717 // -----------------------------------------------------------------------------
2718 // Package XXX_query_objects
2720 * XXX_query_objects:
2721 * - provide all followed entry points
2723 * XXX_occlusion_query2:
2724 * - depends on XXX_query_objects
2725 * - provide ANY_SAMPLES_PASSED
2727 * XXX_occlusion_query_boolean:
2728 * - depends on XXX_occlusion_query2
2729 * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2731 public:
2732 void fDeleteQueries(GLsizei n, const GLuint* names) {
2733 BEFORE_GL_CALL;
2734 ASSERT_SYMBOL_PRESENT(fDeleteQueries);
2735 mSymbols.fDeleteQueries(n, names);
2736 AFTER_GL_CALL;
2737 TRACKING_CONTEXT(DeletedQueries(this, n, names));
2740 void fGenQueries(GLsizei n, GLuint* names) {
2741 BEFORE_GL_CALL;
2742 ASSERT_SYMBOL_PRESENT(fGenQueries);
2743 mSymbols.fGenQueries(n, names);
2744 AFTER_GL_CALL;
2745 TRACKING_CONTEXT(CreatedQueries(this, n, names));
2748 void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
2749 BEFORE_GL_CALL;
2750 ASSERT_SYMBOL_PRESENT(fGetQueryiv);
2751 mSymbols.fGetQueryiv(target, pname, params);
2752 OnSyncCall();
2753 AFTER_GL_CALL;
2756 void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
2757 BEFORE_GL_CALL;
2758 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
2759 mSymbols.fGetQueryObjectuiv(id, pname, params);
2760 OnSyncCall();
2761 AFTER_GL_CALL;
2764 realGLboolean fIsQuery(GLuint query) {
2765 realGLboolean retval = false;
2766 BEFORE_GL_CALL;
2767 ASSERT_SYMBOL_PRESENT(fIsQuery);
2768 retval = mSymbols.fIsQuery(query);
2769 OnSyncCall();
2770 AFTER_GL_CALL;
2771 return retval;
2774 // -----------------------------------------------------------------------------
2775 // Package XXX_get_query_object_i64v
2777 * XXX_get_query_object_i64v:
2778 * - depends on XXX_query_objects
2779 * - provide the followed entry point
2781 public:
2782 void fGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params) {
2783 BEFORE_GL_CALL;
2784 ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v);
2785 mSymbols.fGetQueryObjecti64v(id, pname, params);
2786 OnSyncCall();
2787 AFTER_GL_CALL;
2790 void fGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
2791 BEFORE_GL_CALL;
2792 ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v);
2793 mSymbols.fGetQueryObjectui64v(id, pname, params);
2794 OnSyncCall();
2795 AFTER_GL_CALL;
2798 // -----------------------------------------------------------------------------
2799 // Package XXX_get_query_object_iv
2801 * XXX_get_query_object_iv:
2802 * - depends on XXX_query_objects
2803 * - provide the followed entry point
2805 * XXX_occlusion_query:
2806 * - depends on XXX_get_query_object_iv
2807 * - provide LOCAL_GL_SAMPLES_PASSED
2809 public:
2810 void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
2811 BEFORE_GL_CALL;
2812 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
2813 mSymbols.fGetQueryObjectiv(id, pname, params);
2814 OnSyncCall();
2815 AFTER_GL_CALL;
2818 // -----------------------------------------------------------------------------
2819 // GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
2820 public:
2821 void fBindBufferBase(GLenum target, GLuint index, GLuint buffer) {
2822 BEFORE_GL_CALL;
2823 ASSERT_SYMBOL_PRESENT(fBindBufferBase);
2824 mSymbols.fBindBufferBase(target, index, buffer);
2825 AFTER_GL_CALL;
2828 void fBindBufferRange(GLenum target, GLuint index, GLuint buffer,
2829 GLintptr offset, GLsizeiptr size) {
2830 BEFORE_GL_CALL;
2831 ASSERT_SYMBOL_PRESENT(fBindBufferRange);
2832 mSymbols.fBindBufferRange(target, index, buffer, offset, size);
2833 AFTER_GL_CALL;
2836 void fGenTransformFeedbacks(GLsizei n, GLuint* ids) {
2837 BEFORE_GL_CALL;
2838 ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks);
2839 mSymbols.fGenTransformFeedbacks(n, ids);
2840 OnSyncCall();
2841 AFTER_GL_CALL;
2844 void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) {
2845 BEFORE_GL_CALL;
2846 ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
2847 mSymbols.fDeleteTransformFeedbacks(n, ids);
2848 AFTER_GL_CALL;
2851 realGLboolean fIsTransformFeedback(GLuint id) {
2852 realGLboolean result = false;
2853 BEFORE_GL_CALL;
2854 ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
2855 result = mSymbols.fIsTransformFeedback(id);
2856 OnSyncCall();
2857 AFTER_GL_CALL;
2858 return result;
2861 void fBindTransformFeedback(GLenum target, GLuint id) {
2862 BEFORE_GL_CALL;
2863 ASSERT_SYMBOL_PRESENT(fBindTransformFeedback);
2864 mSymbols.fBindTransformFeedback(target, id);
2865 AFTER_GL_CALL;
2868 void fBeginTransformFeedback(GLenum primitiveMode) {
2869 BEFORE_GL_CALL;
2870 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
2871 mSymbols.fBeginTransformFeedback(primitiveMode);
2872 AFTER_GL_CALL;
2875 void fEndTransformFeedback() {
2876 BEFORE_GL_CALL;
2877 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
2878 mSymbols.fEndTransformFeedback();
2879 AFTER_GL_CALL;
2882 void fTransformFeedbackVaryings(GLuint program, GLsizei count,
2883 const GLchar* const* varyings,
2884 GLenum bufferMode) {
2885 BEFORE_GL_CALL;
2886 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
2887 mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
2888 AFTER_GL_CALL;
2891 void fGetTransformFeedbackVarying(GLuint program, GLuint index,
2892 GLsizei bufSize, GLsizei* length,
2893 GLsizei* size, GLenum* type, GLchar* name) {
2894 BEFORE_GL_CALL;
2895 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
2896 mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size,
2897 type, name);
2898 OnSyncCall();
2899 AFTER_GL_CALL;
2902 void fPauseTransformFeedback() {
2903 BEFORE_GL_CALL;
2904 ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback);
2905 mSymbols.fPauseTransformFeedback();
2906 AFTER_GL_CALL;
2909 void fResumeTransformFeedback() {
2910 BEFORE_GL_CALL;
2911 ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback);
2912 mSymbols.fResumeTransformFeedback();
2913 AFTER_GL_CALL;
2916 void fGetIntegeri_v(GLenum param, GLuint index, GLint* values) {
2917 BEFORE_GL_CALL;
2918 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
2919 mSymbols.fGetIntegeri_v(param, index, values);
2920 OnSyncCall();
2921 AFTER_GL_CALL;
2924 void fGetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
2925 ASSERT_SYMBOL_PRESENT(fGetInteger64i_v);
2926 BEFORE_GL_CALL;
2927 mSymbols.fGetInteger64i_v(target, index, data);
2928 OnSyncCall();
2929 AFTER_GL_CALL;
2932 // -----------------------------------------------------------------------------
2933 // Package XXX_vertex_array_object
2934 public:
2935 void fBindVertexArray(GLuint array) {
2936 BEFORE_GL_CALL;
2937 ASSERT_SYMBOL_PRESENT(fBindVertexArray);
2938 mSymbols.fBindVertexArray(array);
2939 AFTER_GL_CALL;
2942 void fDeleteVertexArrays(GLsizei n, const GLuint* arrays) {
2943 BEFORE_GL_CALL;
2944 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
2945 mSymbols.fDeleteVertexArrays(n, arrays);
2946 AFTER_GL_CALL;
2949 void fGenVertexArrays(GLsizei n, GLuint* arrays) {
2950 BEFORE_GL_CALL;
2951 ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
2952 mSymbols.fGenVertexArrays(n, arrays);
2953 AFTER_GL_CALL;
2956 realGLboolean fIsVertexArray(GLuint array) {
2957 realGLboolean ret = false;
2958 BEFORE_GL_CALL;
2959 ASSERT_SYMBOL_PRESENT(fIsVertexArray);
2960 ret = mSymbols.fIsVertexArray(array);
2961 OnSyncCall();
2962 AFTER_GL_CALL;
2963 return ret;
2966 // -----------------------------------------------------------------------------
2967 // Extension NV_fence
2968 public:
2969 void fGenFences(GLsizei n, GLuint* fences) {
2970 ASSERT_SYMBOL_PRESENT(fGenFences);
2971 BEFORE_GL_CALL;
2972 mSymbols.fGenFences(n, fences);
2973 AFTER_GL_CALL;
2976 void fDeleteFences(GLsizei n, const GLuint* fences) {
2977 ASSERT_SYMBOL_PRESENT(fDeleteFences);
2978 BEFORE_GL_CALL;
2979 mSymbols.fDeleteFences(n, fences);
2980 AFTER_GL_CALL;
2983 void fSetFence(GLuint fence, GLenum condition) {
2984 ASSERT_SYMBOL_PRESENT(fSetFence);
2985 BEFORE_GL_CALL;
2986 mSymbols.fSetFence(fence, condition);
2987 AFTER_GL_CALL;
2990 realGLboolean fTestFence(GLuint fence) {
2991 realGLboolean ret = false;
2992 ASSERT_SYMBOL_PRESENT(fTestFence);
2993 BEFORE_GL_CALL;
2994 ret = mSymbols.fTestFence(fence);
2995 OnSyncCall();
2996 AFTER_GL_CALL;
2997 return ret;
3000 void fFinishFence(GLuint fence) {
3001 ASSERT_SYMBOL_PRESENT(fFinishFence);
3002 BEFORE_GL_CALL;
3003 mSymbols.fFinishFence(fence);
3004 OnSyncCall();
3005 AFTER_GL_CALL;
3008 realGLboolean fIsFence(GLuint fence) {
3009 realGLboolean ret = false;
3010 ASSERT_SYMBOL_PRESENT(fIsFence);
3011 BEFORE_GL_CALL;
3012 ret = mSymbols.fIsFence(fence);
3013 OnSyncCall();
3014 AFTER_GL_CALL;
3015 return ret;
3018 void fGetFenceiv(GLuint fence, GLenum pname, GLint* params) {
3019 ASSERT_SYMBOL_PRESENT(fGetFenceiv);
3020 BEFORE_GL_CALL;
3021 mSymbols.fGetFenceiv(fence, pname, params);
3022 OnSyncCall();
3023 AFTER_GL_CALL;
3026 // -----------------------------------------------------------------------------
3027 // Extension NV_texture_barrier
3028 public:
3029 void fTextureBarrier() {
3030 ASSERT_SYMBOL_PRESENT(fTextureBarrier);
3031 BEFORE_GL_CALL;
3032 mSymbols.fTextureBarrier();
3033 AFTER_GL_CALL;
3036 // Core GL & Extension ARB_copy_buffer
3037 public:
3038 void fCopyBufferSubData(GLenum readtarget, GLenum writetarget,
3039 GLintptr readoffset, GLintptr writeoffset,
3040 GLsizeiptr size) {
3041 BEFORE_GL_CALL;
3042 ASSERT_SYMBOL_PRESENT(fCopyBufferSubData);
3043 mSymbols.fCopyBufferSubData(readtarget, writetarget, readoffset,
3044 writeoffset, size);
3045 AFTER_GL_CALL;
3048 // -----------------------------------------------------------------------------
3049 // Core GL & Extension ARB_map_buffer_range
3050 public:
3051 void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
3052 GLbitfield access) {
3053 void* data = nullptr;
3054 ASSERT_SYMBOL_PRESENT(fMapBufferRange);
3055 BEFORE_GL_CALL;
3056 data = mSymbols.fMapBufferRange(target, offset, length, access);
3057 OnSyncCall();
3058 AFTER_GL_CALL;
3059 return data;
3062 void fFlushMappedBufferRange(GLenum target, GLintptr offset,
3063 GLsizeiptr length) {
3064 ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
3065 BEFORE_GL_CALL;
3066 mSymbols.fFlushMappedBufferRange(target, offset, length);
3067 AFTER_GL_CALL;
3070 // -----------------------------------------------------------------------------
3071 // Core GL & Extension ARB_sampler_objects
3072 public:
3073 void fGenSamplers(GLsizei count, GLuint* samplers) {
3074 BEFORE_GL_CALL;
3075 ASSERT_SYMBOL_PRESENT(fGenSamplers);
3076 mSymbols.fGenSamplers(count, samplers);
3077 AFTER_GL_CALL;
3080 void fDeleteSamplers(GLsizei count, const GLuint* samplers) {
3081 BEFORE_GL_CALL;
3082 ASSERT_SYMBOL_PRESENT(fDeleteSamplers);
3083 mSymbols.fDeleteSamplers(count, samplers);
3084 AFTER_GL_CALL;
3087 realGLboolean fIsSampler(GLuint sampler) {
3088 realGLboolean result = false;
3089 BEFORE_GL_CALL;
3090 ASSERT_SYMBOL_PRESENT(fIsSampler);
3091 result = mSymbols.fIsSampler(sampler);
3092 OnSyncCall();
3093 AFTER_GL_CALL;
3094 return result;
3097 void fBindSampler(GLuint unit, GLuint sampler) {
3098 BEFORE_GL_CALL;
3099 ASSERT_SYMBOL_PRESENT(fBindSampler);
3100 mSymbols.fBindSampler(unit, sampler);
3101 AFTER_GL_CALL;
3104 void fSamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
3105 BEFORE_GL_CALL;
3106 ASSERT_SYMBOL_PRESENT(fSamplerParameteri);
3107 mSymbols.fSamplerParameteri(sampler, pname, param);
3108 AFTER_GL_CALL;
3111 void fSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) {
3112 BEFORE_GL_CALL;
3113 ASSERT_SYMBOL_PRESENT(fSamplerParameteriv);
3114 mSymbols.fSamplerParameteriv(sampler, pname, param);
3115 AFTER_GL_CALL;
3118 void fSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
3119 BEFORE_GL_CALL;
3120 ASSERT_SYMBOL_PRESENT(fSamplerParameterf);
3121 mSymbols.fSamplerParameterf(sampler, pname, param);
3122 AFTER_GL_CALL;
3125 void fSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) {
3126 BEFORE_GL_CALL;
3127 ASSERT_SYMBOL_PRESENT(fSamplerParameterfv);
3128 mSymbols.fSamplerParameterfv(sampler, pname, param);
3129 AFTER_GL_CALL;
3132 void fGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) {
3133 BEFORE_GL_CALL;
3134 ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv);
3135 mSymbols.fGetSamplerParameteriv(sampler, pname, params);
3136 AFTER_GL_CALL;
3139 void fGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
3140 BEFORE_GL_CALL;
3141 ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv);
3142 mSymbols.fGetSamplerParameterfv(sampler, pname, params);
3143 AFTER_GL_CALL;
3146 // -----------------------------------------------------------------------------
3147 // Core GL & Extension ARB_uniform_buffer_object
3148 public:
3149 void fGetUniformIndices(GLuint program, GLsizei uniformCount,
3150 const GLchar* const* uniformNames,
3151 GLuint* uniformIndices) {
3152 ASSERT_SYMBOL_PRESENT(fGetUniformIndices);
3153 BEFORE_GL_CALL;
3154 mSymbols.fGetUniformIndices(program, uniformCount, uniformNames,
3155 uniformIndices);
3156 OnSyncCall();
3157 AFTER_GL_CALL;
3160 void fGetActiveUniformsiv(GLuint program, GLsizei uniformCount,
3161 const GLuint* uniformIndices, GLenum pname,
3162 GLint* params) {
3163 ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
3164 BEFORE_GL_CALL;
3165 mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname,
3166 params);
3167 OnSyncCall();
3168 AFTER_GL_CALL;
3171 GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
3172 GLuint result = 0;
3173 ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
3174 BEFORE_GL_CALL;
3175 result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
3176 OnSyncCall();
3177 AFTER_GL_CALL;
3178 return result;
3181 void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
3182 GLenum pname, GLint* params) {
3183 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv);
3184 BEFORE_GL_CALL;
3185 mSymbols.fGetActiveUniformBlockiv(program, uniformBlockIndex, pname,
3186 params);
3187 OnSyncCall();
3188 AFTER_GL_CALL;
3191 void fGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex,
3192 GLsizei bufSize, GLsizei* length,
3193 GLchar* uniformBlockName) {
3194 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName);
3195 BEFORE_GL_CALL;
3196 mSymbols.fGetActiveUniformBlockName(program, uniformBlockIndex, bufSize,
3197 length, uniformBlockName);
3198 OnSyncCall();
3199 AFTER_GL_CALL;
3202 void fUniformBlockBinding(GLuint program, GLuint uniformBlockIndex,
3203 GLuint uniformBlockBinding) {
3204 ASSERT_SYMBOL_PRESENT(fUniformBlockBinding);
3205 BEFORE_GL_CALL;
3206 mSymbols.fUniformBlockBinding(program, uniformBlockIndex,
3207 uniformBlockBinding);
3208 AFTER_GL_CALL;
3211 // -----------------------------------------------------------------------------
3212 // Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
3213 void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
3214 GLsizei width, GLsizei height) {
3215 BEFORE_GL_CALL;
3216 ASSERT_SYMBOL_PRESENT(fTexStorage2D);
3217 mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
3218 OnSyncCall();
3219 AFTER_GL_CALL;
3222 void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
3223 GLsizei width, GLsizei height, GLsizei depth) {
3224 BEFORE_GL_CALL;
3225 ASSERT_SYMBOL_PRESENT(fTexStorage3D);
3226 mSymbols.fTexStorage3D(target, levels, internalformat, width, height,
3227 depth);
3228 OnSyncCall();
3229 AFTER_GL_CALL;
3232 // -----------------------------------------------------------------------------
3233 // 3D Textures
3234 void fTexImage3D(GLenum target, GLint level, GLint internalFormat,
3235 GLsizei width, GLsizei height, GLsizei depth, GLint border,
3236 GLenum format, GLenum type, const GLvoid* data) {
3237 BEFORE_GL_CALL;
3238 ASSERT_SYMBOL_PRESENT(fTexImage3D);
3239 mSymbols.fTexImage3D(target, level, internalFormat, width, height, depth,
3240 border, format, type, data);
3241 OnSyncCall();
3242 AFTER_GL_CALL;
3245 void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
3246 GLint zoffset, GLsizei width, GLsizei height,
3247 GLsizei depth, GLenum format, GLenum type,
3248 const GLvoid* pixels) {
3249 BEFORE_GL_CALL;
3250 ASSERT_SYMBOL_PRESENT(fTexSubImage3D);
3251 mSymbols.fTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
3252 height, depth, format, type, pixels);
3253 OnSyncCall();
3254 AFTER_GL_CALL;
3257 void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
3258 GLint yoffset, GLint zoffset, GLint x, GLint y,
3259 GLsizei width, GLsizei height) {
3260 BeforeGLReadCall();
3261 BEFORE_GL_CALL;
3262 ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D);
3263 mSymbols.fCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y,
3264 width, height);
3265 AFTER_GL_CALL;
3266 AfterGLReadCall();
3269 void fCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
3270 GLsizei width, GLsizei height, GLsizei depth,
3271 GLint border, GLsizei imageSize,
3272 const GLvoid* data) {
3273 BEFORE_GL_CALL;
3274 ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D);
3275 mSymbols.fCompressedTexImage3D(target, level, internalformat, width, height,
3276 depth, border, imageSize, data);
3277 AFTER_GL_CALL;
3280 void fCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
3281 GLint yoffset, GLint zoffset, GLsizei width,
3282 GLsizei height, GLsizei depth, GLenum format,
3283 GLsizei imageSize, const GLvoid* data) {
3284 BEFORE_GL_CALL;
3285 ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D);
3286 mSymbols.fCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset,
3287 width, height, depth, format, imageSize,
3288 data);
3289 AFTER_GL_CALL;
3292 // -----------------------------------------------------------------------------
3293 // GL3+, ES3+
3295 const GLubyte* fGetStringi(GLenum name, GLuint index) {
3296 const GLubyte* ret = nullptr;
3297 BEFORE_GL_CALL;
3298 ASSERT_SYMBOL_PRESENT(fGetStringi);
3299 ret = mSymbols.fGetStringi(name, index);
3300 OnSyncCall();
3301 AFTER_GL_CALL;
3302 return ret;
3305 // -----------------------------------------------------------------------------
3306 // APPLE_framebuffer_multisample
3308 void fResolveMultisampleFramebufferAPPLE() {
3309 BEFORE_GL_CALL;
3310 ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE);
3311 mSymbols.fResolveMultisampleFramebufferAPPLE();
3312 AFTER_GL_CALL;
3315 // -----------------------------------------------------------------------------
3316 // APPLE_fence
3318 void fFinishObjectAPPLE(GLenum object, GLint name) {
3319 BEFORE_GL_CALL;
3320 ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE);
3321 mSymbols.fFinishObjectAPPLE(object, name);
3322 AFTER_GL_CALL;
3325 realGLboolean fTestObjectAPPLE(GLenum object, GLint name) {
3326 realGLboolean ret = false;
3327 BEFORE_GL_CALL;
3328 ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE);
3329 ret = mSymbols.fTestObjectAPPLE(object, name);
3330 AFTER_GL_CALL;
3331 return ret;
3334 // -----------------------------------------------------------------------------
3335 // prim_restart
3337 void fPrimitiveRestartIndex(GLuint index) {
3338 BEFORE_GL_CALL;
3339 ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex);
3340 mSymbols.fPrimitiveRestartIndex(index);
3341 AFTER_GL_CALL;
3344 // -----------------------------------------------------------------------------
3345 // multiview
3347 void fFramebufferTextureMultiview(GLenum target, GLenum attachment,
3348 GLuint texture, GLint level,
3349 GLint baseViewIndex,
3350 GLsizei numViews) const {
3351 BEFORE_GL_CALL;
3352 ASSERT_SYMBOL_PRESENT(fFramebufferTextureMultiview);
3353 mSymbols.fFramebufferTextureMultiview(target, attachment, texture, level,
3354 baseViewIndex, numViews);
3355 AFTER_GL_CALL;
3358 // -
3359 // draw_buffers_indexed
3361 void fBlendEquationSeparatei(GLuint i, GLenum modeRGB,
3362 GLenum modeAlpha) const {
3363 BEFORE_GL_CALL;
3364 mSymbols.fBlendEquationSeparatei(i, modeRGB, modeAlpha);
3365 AFTER_GL_CALL;
3368 void fBlendFuncSeparatei(GLuint i, GLenum sfactorRGB, GLenum dfactorRGB,
3369 GLenum sfactorAlpha, GLenum dfactorAlpha) const {
3370 BEFORE_GL_CALL;
3371 mSymbols.fBlendFuncSeparatei(i, sfactorRGB, dfactorRGB, sfactorAlpha,
3372 dfactorAlpha);
3373 AFTER_GL_CALL;
3376 void fColorMaski(GLuint i, realGLboolean red, realGLboolean green,
3377 realGLboolean blue, realGLboolean alpha) const {
3378 BEFORE_GL_CALL;
3379 mSymbols.fColorMaski(i, red, green, blue, alpha);
3380 AFTER_GL_CALL;
3383 void fDisablei(GLenum capability, GLuint i) const {
3384 BEFORE_GL_CALL;
3385 mSymbols.fDisablei(capability, i);
3386 AFTER_GL_CALL;
3389 void fEnablei(GLenum capability, GLuint i) const {
3390 BEFORE_GL_CALL;
3391 mSymbols.fEnablei(capability, i);
3392 AFTER_GL_CALL;
3395 // -
3397 void fProvokingVertex(GLenum mode) const {
3398 BEFORE_GL_CALL;
3399 mSymbols.fProvokingVertex(mode);
3400 AFTER_GL_CALL;
3403 // -
3405 #undef BEFORE_GL_CALL
3406 #undef AFTER_GL_CALL
3407 #undef ASSERT_SYMBOL_PRESENT
3408 // #undef TRACKING_CONTEXT // Needed in GLContext.cpp
3409 #undef ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL
3411 // -----------------------------------------------------------------------------
3412 // Constructor
3413 protected:
3414 explicit GLContext(const GLContextDesc&, GLContext* sharedContext = nullptr,
3415 bool canUseTLSIsCurrent = false);
3417 // -----------------------------------------------------------------------------
3418 // Destructor
3419 public:
3420 virtual ~GLContext();
3422 // Mark this context as destroyed. This will nullptr out all
3423 // the GL function pointers!
3424 void MarkDestroyed();
3426 protected:
3427 virtual void OnMarkDestroyed() {}
3429 // -----------------------------------------------------------------------------
3430 // Everything that isn't standard GL APIs
3431 protected:
3432 typedef gfx::SurfaceFormat SurfaceFormat;
3434 public:
3435 virtual void ReleaseSurface() {}
3437 bool IsDestroyed() const {
3438 // MarkDestroyed will mark all these as null.
3439 return mContextLost && mSymbols.fUseProgram == nullptr;
3442 GLContext* GetSharedContext() { return mSharedContext; }
3445 * Returns true if the thread on which this context was created is the
3446 * currently executing thread.
3448 bool IsValidOwningThread() const;
3450 static void PlatformStartup();
3452 public:
3454 * If this context wraps a double-buffered target, swap the back
3455 * and front buffers. It should be assumed that after a swap, the
3456 * contents of the new back buffer are undefined.
3458 virtual bool SwapBuffers() { return false; }
3461 * Stores a damage region (in origin bottom left coordinates), which
3462 * makes the next SwapBuffers call do eglSwapBuffersWithDamage if supported.
3464 * Note that even if only part of the context is damaged, the entire buffer
3465 * needs to be filled with up-to-date contents. This region is only a hint
3466 * telling the system compositor which parts of the buffer were updated.
3468 virtual void SetDamage(const nsIntRegion& aDamageRegion) {}
3471 * Get the buffer age. If it returns 0, that indicates the buffer state is
3472 * unknown and the entire frame should be redrawn.
3474 virtual GLint GetBufferAge() const { return 0; }
3477 * Defines a two-dimensional texture image for context target surface
3479 virtual bool BindTexImage() { return false; }
3481 * Releases a color buffer that is being used as a texture
3483 virtual bool ReleaseTexImage() { return false; }
3485 virtual Maybe<SymbolLoader> GetSymbolLoader() const = 0;
3487 void BindFB(GLuint fb) {
3488 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
3489 MOZ_GL_ASSERT(this, !fb || fIsFramebuffer(fb));
3492 void BindDrawFB(GLuint fb) {
3493 fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
3496 void BindReadFB(GLuint fb) {
3497 fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
3500 GLuint GetDrawFB() const {
3501 return GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT);
3504 GLuint GetReadFB() const {
3505 auto bindEnum = LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT;
3506 if (!IsSupported(GLFeature::split_framebuffer)) {
3507 bindEnum = LOCAL_GL_FRAMEBUFFER_BINDING;
3509 return GetIntAs<GLuint>(bindEnum);
3512 GLuint GetFB() const {
3513 const auto ret = GetDrawFB();
3514 MOZ_ASSERT(ret == GetReadFB());
3515 return ret;
3518 private:
3519 void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype,
3520 GLint* range, GLint* precision) {
3521 switch (precisiontype) {
3522 case LOCAL_GL_LOW_FLOAT:
3523 case LOCAL_GL_MEDIUM_FLOAT:
3524 case LOCAL_GL_HIGH_FLOAT:
3525 // Assume IEEE 754 precision
3526 range[0] = 127;
3527 range[1] = 127;
3528 *precision = 23;
3529 break;
3530 case LOCAL_GL_LOW_INT:
3531 case LOCAL_GL_MEDIUM_INT:
3532 case LOCAL_GL_HIGH_INT:
3533 // Some (most) hardware only supports single-precision floating-point
3534 // numbers, which can accurately represent integers up to +/-16777216
3535 range[0] = 24;
3536 range[1] = 24;
3537 *precision = 0;
3538 break;
3542 public:
3543 virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
3545 virtual GLenum GetPreferredEGLImageTextureTarget() const {
3546 #ifdef MOZ_WIDGET_GTK
3547 return LOCAL_GL_TEXTURE_2D;
3548 #else
3549 return IsExtensionSupported(OES_EGL_image_external)
3550 ? LOCAL_GL_TEXTURE_EXTERNAL
3551 : LOCAL_GL_TEXTURE_2D;
3552 #endif
3555 virtual bool RenewSurface(widget::CompositorWidget* aWidget) { return false; }
3557 // Shared code for GL extensions and GLX extensions.
3558 static bool ListHasExtension(const GLubyte* extensions,
3559 const char* extension);
3561 public:
3562 enum {
3563 DebugFlagEnabled = 1 << 0,
3564 DebugFlagTrace = 1 << 1,
3565 DebugFlagAbortOnError = 1 << 2
3568 const uint8_t mDebugFlags;
3569 static uint8_t ChooseDebugFlags(CreateContextFlags createFlags);
3571 protected:
3572 RefPtr<GLContext> mSharedContext;
3574 public:
3575 // The thread id which this context was created.
3576 Maybe<PlatformThreadId> mOwningThreadId;
3578 protected:
3579 GLContextSymbols mSymbols = {};
3581 UniquePtr<GLBlitHelper> mBlitHelper;
3582 UniquePtr<GLReadTexImageHelper> mReadTexImageHelper;
3584 public:
3585 GLBlitHelper* BlitHelper();
3586 GLReadTexImageHelper* ReadTexImageHelper();
3588 // Assumes shares are created by all sharing with the same global context.
3589 bool SharesWith(const GLContext* other) const {
3590 MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
3591 MOZ_ASSERT(!other->mSharedContext ||
3592 !other->mSharedContext->mSharedContext);
3593 MOZ_ASSERT(!this->mSharedContext || !other->mSharedContext ||
3594 this->mSharedContext == other->mSharedContext);
3596 const GLContext* thisShared =
3597 this->mSharedContext ? this->mSharedContext : this;
3598 const GLContext* otherShared =
3599 other->mSharedContext ? other->mSharedContext : other;
3601 return thisShared == otherShared;
3604 bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
3606 // Does not check completeness.
3607 void AttachBuffersToFB(GLuint colorTex, GLuint colorRB, GLuint depthRB,
3608 GLuint stencilRB, GLuint fb,
3609 GLenum target = LOCAL_GL_TEXTURE_2D);
3611 // Passing null is fine if the value you'd get is 0.
3612 bool AssembleOffscreenFBs(const GLuint colorMSRB, const GLuint depthRB,
3613 const GLuint stencilRB, const GLuint texture,
3614 GLuint* drawFB, GLuint* readFB);
3616 protected:
3617 SharedSurface* mLockedSurface = nullptr;
3619 public:
3620 void LockSurface(SharedSurface* surf) { mLockedSurface = surf; }
3622 void UnlockSurface(SharedSurface* surf) {
3623 MOZ_ASSERT(mLockedSurface == surf);
3624 mLockedSurface = nullptr;
3627 SharedSurface* GetLockedSurface() const { return mLockedSurface; }
3629 bool IsOffscreen() const { return mDesc.isOffscreen; }
3631 bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
3633 bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
3635 virtual bool Init();
3637 private:
3638 bool InitImpl();
3639 void LoadMoreSymbols(const SymbolLoader& loader);
3640 bool LoadExtSymbols(const SymbolLoader& loader, const SymLoadStruct* list,
3641 GLExtensions ext);
3642 bool LoadFeatureSymbols(const SymbolLoader& loader, const SymLoadStruct* list,
3643 GLFeature feature);
3645 protected:
3646 void InitExtensions();
3648 GLint mViewportRect[4] = {};
3649 GLint mScissorRect[4] = {};
3651 uint32_t mMaxTexOrRbSize = 0;
3652 GLint mMaxTextureSize = 0;
3653 GLint mMaxCubeMapTextureSize = 0;
3654 GLint mMaxRenderbufferSize = 0;
3655 GLint mMaxViewportDims[2] = {};
3656 GLsizei mMaxSamples = 0;
3657 bool mNeedsTextureSizeChecks = false;
3658 bool mNeedsFlushBeforeDeleteFB = false;
3659 bool mTextureAllocCrashesOnMapFailure = false;
3660 bool mNeedsCheckAfterAttachTextureToFb = false;
3661 const bool mWorkAroundDriverBugs;
3662 mutable uint64_t mSyncGLCallCount = 0;
3664 bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width,
3665 GLsizei height) const {
3666 if (mNeedsTextureSizeChecks) {
3667 // some drivers incorrectly handle some large texture sizes that are below
3668 // the max texture size that they report. So we check ourselves against
3669 // our own values (mMax[CubeMap]TextureSize). see bug 737182 for Mac Intel
3670 // 2D textures see bug 684882 for Mac Intel cube map textures see bug
3671 // 814716 for Mesa Nouveau
3672 GLsizei maxSize =
3673 target == LOCAL_GL_TEXTURE_CUBE_MAP ||
3674 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
3675 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3676 ? mMaxCubeMapTextureSize
3677 : mMaxTextureSize;
3678 return width <= maxSize && height <= maxSize;
3680 return true;
3683 public:
3684 auto MaxSamples() const { return uint32_t(mMaxSamples); }
3685 auto MaxTextureSize() const { return uint32_t(mMaxTextureSize); }
3686 auto MaxRenderbufferSize() const { return uint32_t(mMaxRenderbufferSize); }
3687 auto MaxTexOrRbSize() const { return mMaxTexOrRbSize; }
3689 #ifdef MOZ_GL_DEBUG_BUILD
3690 void CreatedProgram(GLContext* aOrigin, GLuint aName);
3691 void CreatedShader(GLContext* aOrigin, GLuint aName);
3692 void CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3693 void CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3694 void CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3695 void CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3696 void CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3697 void DeletedProgram(GLContext* aOrigin, GLuint aName);
3698 void DeletedShader(GLContext* aOrigin, GLuint aName);
3699 void DeletedBuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3700 void DeletedQueries(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3701 void DeletedTextures(GLContext* aOrigin, GLsizei aCount,
3702 const GLuint* aNames);
3703 void DeletedFramebuffers(GLContext* aOrigin, GLsizei aCount,
3704 const GLuint* aNames);
3705 void DeletedRenderbuffers(GLContext* aOrigin, GLsizei aCount,
3706 const GLuint* aNames);
3708 void SharedContextDestroyed(GLContext* aChild);
3709 void ReportOutstandingNames();
3711 struct NamedResource {
3712 NamedResource() : origin(nullptr), name(0), originDeleted(false) {}
3714 NamedResource(GLContext* aOrigin, GLuint aName)
3715 : origin(aOrigin), name(aName), originDeleted(false) {}
3717 GLContext* origin;
3718 GLuint name;
3719 bool originDeleted;
3721 // for sorting
3722 bool operator<(const NamedResource& aOther) const {
3723 if (intptr_t(origin) < intptr_t(aOther.origin)) return true;
3724 if (name < aOther.name) return true;
3725 return false;
3727 bool operator==(const NamedResource& aOther) const {
3728 return origin == aOther.origin && name == aOther.name &&
3729 originDeleted == aOther.originDeleted;
3733 nsTArray<NamedResource> mTrackedPrograms;
3734 nsTArray<NamedResource> mTrackedShaders;
3735 nsTArray<NamedResource> mTrackedTextures;
3736 nsTArray<NamedResource> mTrackedFramebuffers;
3737 nsTArray<NamedResource> mTrackedRenderbuffers;
3738 nsTArray<NamedResource> mTrackedBuffers;
3739 nsTArray<NamedResource> mTrackedQueries;
3740 #endif
3742 protected:
3743 bool mHeavyGLCallsSinceLastFlush = false;
3745 public:
3746 void FlushIfHeavyGLCallsSinceLastFlush();
3747 static bool ShouldSpew();
3748 static bool ShouldDumpExts();
3750 // --
3752 void TexParams_SetClampNoMips(GLenum target = LOCAL_GL_TEXTURE_2D) {
3753 fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
3754 fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
3755 fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
3756 fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
3759 // --
3761 GLuint CreateFramebuffer() {
3762 GLuint x = 0;
3763 fGenFramebuffers(1, &x);
3764 return x;
3766 GLuint CreateRenderbuffer() {
3767 GLuint x = 0;
3768 fGenRenderbuffers(1, &x);
3769 return x;
3771 GLuint CreateTexture() {
3772 GLuint x = 0;
3773 fGenTextures(1, &x);
3774 return x;
3777 void DeleteFramebuffer(const GLuint x) { fDeleteFramebuffers(1, &x); }
3778 void DeleteRenderbuffer(const GLuint x) { fDeleteRenderbuffers(1, &x); }
3779 void DeleteTexture(const GLuint x) { fDeleteTextures(1, &x); }
3782 bool DoesStringMatch(const char* aString, const char* aWantedString);
3784 void SplitByChar(const nsACString& str, const char delim,
3785 std::vector<nsCString>* const out);
3787 template <size_t N>
3788 bool MarkBitfieldByString(const nsACString& str,
3789 const char* const (&markStrList)[N],
3790 std::bitset<N>* const out_markList) {
3791 for (size_t i = 0; i < N; i++) {
3792 if (str.Equals(markStrList[i])) {
3793 (*out_markList)[i] = 1;
3794 return true;
3797 return false;
3800 template <size_t N>
3801 void MarkBitfieldByStrings(const std::vector<nsCString>& strList,
3802 bool dumpStrings,
3803 const char* const (&markStrList)[N],
3804 std::bitset<N>* const out_markList) {
3805 for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
3806 const nsACString& str = *itr;
3807 const bool wasMarked = MarkBitfieldByString(str, markStrList, out_markList);
3808 if (dumpStrings)
3809 printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
3813 // -
3815 class Renderbuffer final {
3816 public:
3817 const WeakPtr<GLContext> weakGl;
3818 const GLuint name;
3820 private:
3821 static GLuint Create(GLContext& gl) {
3822 GLuint ret = 0;
3823 gl.fGenRenderbuffers(1, &ret);
3824 return ret;
3827 public:
3828 explicit Renderbuffer(GLContext& gl) : weakGl(&gl), name(Create(gl)) {}
3830 ~Renderbuffer() {
3831 const RefPtr<GLContext> gl = weakGl.get();
3832 if (!gl || !gl->MakeCurrent()) return;
3833 gl->fDeleteRenderbuffers(1, &name);
3837 // -
3839 class Texture final {
3840 public:
3841 const WeakPtr<GLContext> weakGl;
3842 const GLuint name;
3844 private:
3845 static GLuint Create(GLContext& gl) {
3846 GLuint ret = 0;
3847 gl.fGenTextures(1, &ret);
3848 return ret;
3851 public:
3852 explicit Texture(GLContext& gl) : weakGl(&gl), name(Create(gl)) {}
3854 ~Texture() {
3855 const RefPtr<GLContext> gl = weakGl.get();
3856 if (!gl || !gl->MakeCurrent()) return;
3857 gl->fDeleteTextures(1, &name);
3862 * Helper function that creates a 2D texture aSize.width x aSize.height with
3863 * storage type specified by aFormats. Returns GL texture object id.
3865 * See mozilla::gl::CreateTexture.
3867 UniquePtr<Texture> CreateTexture(GLContext&, const gfx::IntSize& size);
3870 * Helper function that calculates the number of bytes required per
3871 * texel for a texture from its format and type.
3873 uint32_t GetBytesPerTexel(GLenum format, GLenum type);
3875 void MesaMemoryLeakWorkaround();
3877 } /* namespace gl */
3878 } /* namespace mozilla */
3880 #endif /* GLCONTEXT_H_ */