Bug 1890689 accumulate input in LargerReceiverBlockSizeThanDesiredBuffering GTest...
[gecko.git] / gfx / gl / GLContext.h
blobeea26024ae40003c4ffc4db0428e0323ea76f243
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 "nsRegionFwd.h"
41 #include "nsString.h"
42 #include "GLContextTypes.h"
43 #include "GLContextSymbols.h"
44 #include "base/platform_thread.h" // for PlatformThreadId
45 #include "mozilla/GenericRefCounted.h"
46 #include "mozilla/WeakPtr.h"
48 #ifdef MOZ_WIDGET_ANDROID
49 # include "mozilla/ProfilerLabels.h"
50 #endif
52 namespace mozilla {
54 namespace gl {
55 class GLBlitHelper;
56 class GLLibraryEGL;
57 class GLReadTexImageHelper;
58 class SharedSurface;
59 class SymbolLoader;
60 struct SymLoadStruct;
61 } // namespace gl
63 namespace layers {
64 class ColorTextureLayerProgram;
65 } // namespace layers
67 namespace widget {
68 class CompositorWidget;
69 } // namespace widget
70 } // namespace mozilla
72 namespace mozilla {
73 namespace gl {
75 enum class GLFeature {
76 bind_buffer_offset,
77 blend_minmax,
78 clear_buffers,
79 copy_buffer,
80 depth_texture,
81 draw_buffers,
82 draw_buffers_indexed,
83 draw_instanced,
84 element_index_uint,
85 ES2_compatibility,
86 ES3_compatibility,
87 EXT_color_buffer_float,
88 frag_color_float,
89 frag_depth,
90 framebuffer_blit,
91 framebuffer_multisample,
92 framebuffer_object,
93 framebuffer_object_EXT_OES,
94 get_integer_indexed,
95 get_integer64_indexed,
96 get_query_object_i64v,
97 get_query_object_iv,
98 gpu_shader4,
99 instanced_arrays,
100 instanced_non_arrays,
101 internalformat_query,
102 invalidate_framebuffer,
103 map_buffer_range,
104 multiview,
105 occlusion_query,
106 occlusion_query_boolean,
107 occlusion_query2,
108 packed_depth_stencil,
109 prim_restart,
110 prim_restart_fixed,
111 provoking_vertex,
112 query_counter,
113 query_objects,
114 query_time_elapsed,
115 read_buffer,
116 renderbuffer_color_float,
117 renderbuffer_color_half_float,
118 robust_buffer_access_behavior,
119 robustness,
120 sRGB,
121 sampler_objects,
122 seamless_cube_map_opt_in,
123 shader_texture_lod,
124 split_framebuffer,
125 standard_derivatives,
126 sync,
127 texture_3D,
128 texture_3D_compressed,
129 texture_3D_copy,
130 texture_compression_bptc,
131 texture_compression_rgtc,
132 texture_float,
133 texture_float_linear,
134 texture_half_float,
135 texture_half_float_linear,
136 texture_non_power_of_two,
137 texture_norm16,
138 texture_rg,
139 texture_storage,
140 texture_swizzle,
141 transform_feedback2,
142 uniform_buffer_object,
143 uniform_matrix_nonsquare,
144 vertex_array_object,
145 EnumMax
148 enum class ContextProfile : uint8_t {
149 Unknown = 0,
150 OpenGLCore,
151 OpenGLCompatibility,
152 OpenGLES
155 enum class GLRenderer {
156 Adreno200,
157 Adreno205,
158 AdrenoTM200,
159 AdrenoTM205,
160 AdrenoTM305,
161 AdrenoTM320,
162 AdrenoTM330,
163 AdrenoTM420,
164 Mali400MP,
165 Mali450MP,
166 MaliT,
167 SGX530,
168 SGX540,
169 SGX544MP,
170 Tegra,
171 AndroidEmulator,
172 GalliumLlvmpipe,
173 IntelHD3000,
174 MicrosoftBasicRenderDriver,
175 SamsungXclipse,
176 Other
179 class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
180 public:
181 static MOZ_THREAD_LOCAL(const GLContext*) sCurrentContext;
183 static void InvalidateCurrentContext();
185 const GLContextDesc mDesc;
187 bool mImplicitMakeCurrent = false;
188 bool mUseTLSIsCurrent;
190 static void ResetTLSCurrentContext();
192 class TlsScope final {
193 const WeakPtr<GLContext> mGL;
194 const bool mWasTlsOk;
196 public:
197 explicit TlsScope(GLContext* const gl, bool invalidate = false)
198 : mGL(gl), mWasTlsOk(gl && gl->mUseTLSIsCurrent) {
199 if (mGL) {
200 if (invalidate) {
201 InvalidateCurrentContext();
203 mGL->mUseTLSIsCurrent = true;
207 ~TlsScope() {
208 if (mGL) {
209 mGL->mUseTLSIsCurrent = mWasTlsOk;
214 // -----------------------------------------------------------------------------
215 // basic getters
216 public:
218 * Returns true if the context is using ANGLE. This should only be overridden
219 * for an ANGLE implementation.
221 virtual bool IsANGLE() const { return false; }
224 * Returns true if the context is using WARP. This should only be overridden
225 * for an ANGLE implementation.
227 virtual bool IsWARP() const { return false; }
229 virtual void GetWSIInfo(nsCString* const out) const = 0;
232 * Return true if we are running on a OpenGL core profile context
234 inline bool IsCoreProfile() const {
235 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
237 return mProfile == ContextProfile::OpenGLCore;
241 * Return true if we are running on a OpenGL compatibility profile context
242 * (legacy profile 2.1 on Max OS X)
244 inline bool IsCompatibilityProfile() const {
245 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
247 return mProfile == ContextProfile::OpenGLCompatibility;
250 inline bool IsGLES() const {
251 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
253 return mProfile == ContextProfile::OpenGLES;
256 inline bool IsAtLeast(ContextProfile profile, unsigned int version) const {
257 MOZ_ASSERT(profile != ContextProfile::Unknown,
258 "IsAtLeast: bad <profile> parameter");
259 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
260 MOZ_ASSERT(mVersion != 0, "unknown context version");
262 if (version > mVersion) {
263 return false;
266 return profile == mProfile;
270 * Return the version of the context.
271 * Example :
272 * If this a OpenGL 2.1, that will return 210
274 inline uint32_t Version() const { return mVersion; }
276 inline uint32_t ShadingLanguageVersion() const {
277 return mShadingLanguageVersion;
280 GLVendor Vendor() const { return mVendor; }
281 GLRenderer Renderer() const { return mRenderer; }
282 bool IsMesa() const { return mIsMesa; }
284 bool IsContextLost() const { return mContextLost; }
286 bool CheckContextLost() const {
287 mTopError = GetError();
288 return IsContextLost();
291 bool HasPBOState() const { return (!IsGLES() || Version() >= 300); }
294 * If this context is double-buffered, returns TRUE.
296 virtual bool IsDoubleBuffered() const { return false; }
298 virtual GLContextType GetContextType() const = 0;
300 virtual bool IsCurrentImpl() const = 0;
301 virtual bool MakeCurrentImpl() const = 0;
303 bool IsCurrent() const {
304 if (mImplicitMakeCurrent) return MakeCurrent();
306 return IsCurrentImpl();
309 bool MakeCurrent(bool aForce = false) const;
312 * Get the default framebuffer for this context.
314 UniquePtr<MozFramebuffer> mOffscreenDefaultFb;
316 bool CreateOffscreenDefaultFb(const gfx::IntSize& size);
318 virtual GLuint GetDefaultFramebuffer() {
319 if (mOffscreenDefaultFb) {
320 return mOffscreenDefaultFb->mFB;
322 return 0;
326 * mVersion store the OpenGL's version, multiplied by 100. For example, if
327 * the context is an OpenGL 2.1 context, mVersion value will be 210.
329 uint32_t mVersion = 0;
330 ContextProfile mProfile = ContextProfile::Unknown;
332 uint32_t mShadingLanguageVersion = 0;
334 GLVendor mVendor = GLVendor::Other;
335 GLRenderer mRenderer = GLRenderer::Other;
336 bool mIsMesa = false;
338 // -----------------------------------------------------------------------------
339 // Extensions management
341 * This mechanism is designed to know if an extension is supported. In the
342 * long term, we would like to only use the extension group queries XXX_* to
343 * have full compatibility with context version and profiles (especialy the
344 * core that officialy don't bring any extensions).
348 * Known GL extensions that can be queried by
349 * IsExtensionSupported. The results of this are cached, and as
350 * such it's safe to use this even in performance critical code.
351 * If you add to this array, remember to add to the string names
352 * in GLContext.cpp.
354 enum GLExtensions {
355 Extension_None = 0,
356 AMD_compressed_ATC_texture,
357 ANGLE_depth_texture,
358 ANGLE_framebuffer_blit,
359 ANGLE_framebuffer_multisample,
360 ANGLE_instanced_arrays,
361 ANGLE_multiview,
362 ANGLE_provoking_vertex,
363 ANGLE_texture_compression_dxt3,
364 ANGLE_texture_compression_dxt5,
365 ANGLE_timer_query,
366 APPLE_client_storage,
367 APPLE_fence,
368 APPLE_framebuffer_multisample,
369 APPLE_sync,
370 APPLE_texture_range,
371 APPLE_vertex_array_object,
372 ARB_ES2_compatibility,
373 ARB_ES3_compatibility,
374 ARB_color_buffer_float,
375 ARB_compatibility,
376 ARB_copy_buffer,
377 ARB_depth_texture,
378 ARB_draw_buffers,
379 ARB_draw_instanced,
380 ARB_framebuffer_object,
381 ARB_framebuffer_sRGB,
382 ARB_geometry_shader4,
383 ARB_half_float_pixel,
384 ARB_instanced_arrays,
385 ARB_internalformat_query,
386 ARB_invalidate_subdata,
387 ARB_map_buffer_range,
388 ARB_occlusion_query2,
389 ARB_pixel_buffer_object,
390 ARB_provoking_vertex,
391 ARB_robust_buffer_access_behavior,
392 ARB_robustness,
393 ARB_sampler_objects,
394 ARB_seamless_cube_map,
395 ARB_shader_texture_lod,
396 ARB_sync,
397 ARB_texture_compression,
398 ARB_texture_compression_bptc,
399 ARB_texture_compression_rgtc,
400 ARB_texture_float,
401 ARB_texture_non_power_of_two,
402 ARB_texture_rectangle,
403 ARB_texture_rg,
404 ARB_texture_storage,
405 ARB_texture_swizzle,
406 ARB_timer_query,
407 ARB_transform_feedback2,
408 ARB_uniform_buffer_object,
409 ARB_vertex_array_object,
410 CHROMIUM_color_buffer_float_rgb,
411 CHROMIUM_color_buffer_float_rgba,
412 EXT_bgra,
413 EXT_blend_minmax,
414 EXT_color_buffer_float,
415 EXT_color_buffer_half_float,
416 EXT_copy_texture,
417 EXT_disjoint_timer_query,
418 EXT_draw_buffers,
419 EXT_draw_buffers2,
420 EXT_draw_instanced,
421 EXT_float_blend,
422 EXT_frag_depth,
423 EXT_framebuffer_blit,
424 EXT_framebuffer_multisample,
425 EXT_framebuffer_object,
426 EXT_framebuffer_sRGB,
427 EXT_gpu_shader4,
428 EXT_map_buffer_range,
429 EXT_multisampled_render_to_texture,
430 EXT_occlusion_query_boolean,
431 EXT_packed_depth_stencil,
432 EXT_provoking_vertex,
433 EXT_read_format_bgra,
434 EXT_robustness,
435 EXT_sRGB,
436 EXT_sRGB_write_control,
437 EXT_shader_texture_lod,
438 EXT_texture_compression_bptc,
439 EXT_texture_compression_dxt1,
440 EXT_texture_compression_rgtc,
441 EXT_texture_compression_s3tc,
442 EXT_texture_compression_s3tc_srgb,
443 EXT_texture_filter_anisotropic,
444 EXT_texture_format_BGRA8888,
445 EXT_texture_norm16,
446 EXT_texture_sRGB,
447 EXT_texture_storage,
448 EXT_timer_query,
449 EXT_transform_feedback,
450 EXT_unpack_subimage,
451 IMG_read_format,
452 IMG_texture_compression_pvrtc,
453 IMG_texture_npot,
454 KHR_debug,
455 KHR_parallel_shader_compile,
456 KHR_robust_buffer_access_behavior,
457 KHR_robustness,
458 KHR_texture_compression_astc_hdr,
459 KHR_texture_compression_astc_ldr,
460 NV_draw_instanced,
461 NV_fence,
462 NV_framebuffer_blit,
463 NV_geometry_program4,
464 NV_half_float,
465 NV_instanced_arrays,
466 NV_primitive_restart,
467 NV_texture_barrier,
468 NV_transform_feedback,
469 NV_transform_feedback2,
470 OES_EGL_image,
471 OES_EGL_image_external,
472 OES_EGL_sync,
473 OES_compressed_ETC1_RGB8_texture,
474 OES_depth24,
475 OES_depth32,
476 OES_depth_texture,
477 OES_draw_buffers_indexed,
478 OES_element_index_uint,
479 OES_fbo_render_mipmap,
480 OES_framebuffer_object,
481 OES_packed_depth_stencil,
482 OES_rgb8_rgba8,
483 OES_standard_derivatives,
484 OES_stencil8,
485 OES_texture_3D,
486 OES_texture_float,
487 OES_texture_float_linear,
488 OES_texture_half_float,
489 OES_texture_half_float_linear,
490 OES_texture_npot,
491 OES_vertex_array_object,
492 OVR_multiview2,
493 Extensions_Max,
494 Extensions_End
497 bool IsExtensionSupported(GLExtensions aKnownExtension) const {
498 return mAvailableExtensions[aKnownExtension];
501 protected:
502 void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
503 mAvailableExtensions[aKnownExtension] = 0;
506 void MarkExtensionSupported(GLExtensions aKnownExtension) {
507 mAvailableExtensions[aKnownExtension] = 1;
510 std::bitset<Extensions_Max> mAvailableExtensions;
512 // -----------------------------------------------------------------------------
513 // Feature queries
515 * This mecahnism introduces a new way to check if a OpenGL feature is
516 * supported, regardless of whether it is supported by an extension or
517 * natively by the context version/profile
519 public:
520 bool IsSupported(GLFeature feature) const {
521 return mAvailableFeatures[size_t(feature)];
524 static const char* GetFeatureName(GLFeature feature);
526 private:
527 std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
530 * Init features regarding OpenGL extension and context version and profile
532 void InitFeatures();
535 * Mark the feature and associated extensions as unsupported
537 void MarkUnsupported(GLFeature feature);
540 * Is this feature supported using the core (unsuffixed) symbols?
542 bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
544 // -----------------------------------------------------------------------------
545 // Error handling
547 private:
548 mutable bool mContextLost = false;
549 mutable GLenum mTopError = 0;
551 protected:
552 void OnContextLostError() const;
554 public:
555 static std::string GLErrorToString(GLenum aError);
557 static bool IsBadCallError(const GLenum err) {
558 return !(err == 0 || err == LOCAL_GL_CONTEXT_LOST);
561 class LocalErrorScope;
563 private:
564 mutable std::stack<const LocalErrorScope*> mLocalErrorScopeStack;
565 mutable UniquePtr<LocalErrorScope> mDebugErrorScope;
567 ////////////////////////////////////
568 // Use this safer option.
570 public:
571 class LocalErrorScope {
572 const GLContext& mGL;
573 GLenum mOldTop;
574 bool mHasBeenChecked;
576 public:
577 explicit LocalErrorScope(const GLContext& gl)
578 : mGL(gl), mHasBeenChecked(false) {
579 mGL.mLocalErrorScopeStack.push(this);
580 mOldTop = mGL.GetError();
583 /// Never returns CONTEXT_LOST.
584 GLenum GetError() {
585 MOZ_ASSERT(!mHasBeenChecked);
586 mHasBeenChecked = true;
588 const auto ret = mGL.GetError();
589 if (ret == LOCAL_GL_CONTEXT_LOST) return 0;
590 return ret;
593 ~LocalErrorScope() {
594 MOZ_ASSERT(mHasBeenChecked);
596 MOZ_ASSERT(!IsBadCallError(mGL.GetError()));
598 MOZ_ASSERT(mGL.mLocalErrorScopeStack.top() == this);
599 mGL.mLocalErrorScopeStack.pop();
601 mGL.mTopError = mOldTop;
605 // -
607 bool GetPotentialInteger(GLenum pname, GLint* param) {
608 LocalErrorScope localError(*this);
610 fGetIntegerv(pname, param);
612 GLenum err = localError.GetError();
613 MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_INVALID_ENUM);
614 return err == LOCAL_GL_NO_ERROR;
617 void DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity,
618 GLsizei length, const GLchar* message);
620 private:
621 static void GLAPIENTRY StaticDebugCallback(GLenum source, GLenum type,
622 GLuint id, GLenum severity,
623 GLsizei length,
624 const GLchar* message,
625 const GLvoid* userParam);
627 // -----------------------------------------------------------------------------
628 // Debugging implementation
629 private:
630 #ifndef MOZ_FUNCTION_NAME
631 # ifdef __GNUC__
632 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
633 # elif defined(_MSC_VER)
634 # define MOZ_FUNCTION_NAME __FUNCTION__
635 # else
636 # define MOZ_FUNCTION_NAME \
637 __func__ // defined in C99, supported in various C++ compilers. Just raw
638 // function name.
639 # endif
640 #endif
642 #ifdef MOZ_WIDGET_ANDROID
643 // Record the name of the GL call for better hang stacks on Android.
644 # define ANDROID_ONLY_PROFILER_LABEL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
645 #else
646 # define ANDROID_ONLY_PROFILER_LABEL
647 #endif
649 #define BEFORE_GL_CALL \
650 ANDROID_ONLY_PROFILER_LABEL \
651 if (MOZ_LIKELY(BeforeGLCall(MOZ_FUNCTION_NAME))) { \
652 do { \
653 } while (0)
655 #define AFTER_GL_CALL \
656 AfterGLCall(MOZ_FUNCTION_NAME); \
658 do { \
659 } while (0)
661 void BeforeGLCall_Debug(const char* funcName) const;
662 void AfterGLCall_Debug(const char* funcName) const;
663 static void OnImplicitMakeCurrentFailure(const char* funcName);
665 bool BeforeGLCall(const char* const funcName) const {
666 if (mImplicitMakeCurrent) {
667 if (MOZ_UNLIKELY(!MakeCurrent())) {
668 if (!mContextLost) {
669 OnImplicitMakeCurrentFailure(funcName);
671 return false;
674 MOZ_GL_ASSERT(this, IsCurrentImpl());
676 if (MOZ_UNLIKELY(mDebugFlags)) {
677 BeforeGLCall_Debug(funcName);
679 return true;
682 void AfterGLCall(const char* const funcName) const {
683 if (MOZ_UNLIKELY(mDebugFlags)) {
684 AfterGLCall_Debug(funcName);
688 GLContext* TrackingContext() {
689 GLContext* tip = this;
690 while (tip->mSharedContext) tip = tip->mSharedContext;
691 return tip;
694 static void AssertNotPassingStackBufferToTheGL(const void* ptr);
696 #ifdef MOZ_GL_DEBUG_BUILD
698 # define TRACKING_CONTEXT(a) \
699 do { \
700 TrackingContext()->a; \
701 } while (0)
703 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
704 AssertNotPassingStackBufferToTheGL(ptr)
706 # define ASSERT_SYMBOL_PRESENT(func) \
707 do { \
708 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, \
709 "Mismatched symbol check."); \
710 if (MOZ_UNLIKELY(!mSymbols.func)) { \
711 printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", \
712 #func); \
713 MOZ_CRASH("GFX: Uninitialized GL function"); \
715 } while (0)
717 #else // ifdef MOZ_GL_DEBUG_BUILD
719 # define TRACKING_CONTEXT(a) \
720 do { \
721 } while (0)
722 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
723 do { \
724 } while (0)
725 # define ASSERT_SYMBOL_PRESENT(func) \
726 do { \
727 } while (0)
729 #endif // ifdef MOZ_GL_DEBUG_BUILD
731 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
732 // bound.
733 void BeforeGLDrawCall() {}
735 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
736 // if it's bound.
737 void AfterGLDrawCall() { mHeavyGLCallsSinceLastFlush = true; }
739 // Do whatever setup is necessary to read from our offscreen FBO, if it's
740 // bound.
741 void BeforeGLReadCall() {}
743 // Do whatever tear-down is necessary after reading from our offscreen FBO,
744 // if it's bound.
745 void AfterGLReadCall() {}
747 public:
748 void OnSyncCall() const { mSyncGLCallCount++; }
750 uint64_t GetSyncCallCount() const { return mSyncGLCallCount; }
752 void ResetSyncCallCount(const char* resetReason) const;
754 // -----------------------------------------------------------------------------
755 // GL official entry points
756 public:
757 // We smash all errors together, so you never have to loop on this. We
758 // guarantee that immediately after this call, there are no errors left.
759 // Always returns the top-most error, except if followed by CONTEXT_LOST, then
760 // return that instead.
761 GLenum GetError() const;
763 GLenum fGetError() { return GetError(); }
765 GLenum fGetGraphicsResetStatus() const;
767 // -
769 void fActiveTexture(GLenum texture) {
770 BEFORE_GL_CALL;
771 mSymbols.fActiveTexture(texture);
772 AFTER_GL_CALL;
775 void fAttachShader(GLuint program, GLuint shader) {
776 BEFORE_GL_CALL;
777 mSymbols.fAttachShader(program, shader);
778 AFTER_GL_CALL;
781 void fBeginQuery(GLenum target, GLuint id) {
782 BEFORE_GL_CALL;
783 ASSERT_SYMBOL_PRESENT(fBeginQuery);
784 mSymbols.fBeginQuery(target, id);
785 AFTER_GL_CALL;
788 void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
789 BEFORE_GL_CALL;
790 mSymbols.fBindAttribLocation(program, index, name);
791 AFTER_GL_CALL;
794 void fBindBuffer(GLenum target, GLuint buffer) {
795 BEFORE_GL_CALL;
796 mSymbols.fBindBuffer(target, buffer);
797 AFTER_GL_CALL;
800 void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments,
801 const GLenum* attachments) {
802 BeforeGLDrawCall();
803 BEFORE_GL_CALL;
804 ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
805 mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
806 AFTER_GL_CALL;
807 AfterGLDrawCall();
810 void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
811 const GLenum* attachments, GLint x, GLint y,
812 GLsizei width, GLsizei height) {
813 BeforeGLDrawCall();
814 BEFORE_GL_CALL;
815 ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
816 mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x,
817 y, width, height);
818 AFTER_GL_CALL;
819 AfterGLDrawCall();
822 void fBindTexture(GLenum target, GLuint texture) {
823 BEFORE_GL_CALL;
824 mSymbols.fBindTexture(target, texture);
825 AFTER_GL_CALL;
828 void fBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
829 BEFORE_GL_CALL;
830 mSymbols.fBlendColor(red, green, blue, alpha);
831 AFTER_GL_CALL;
834 void fBlendEquation(GLenum mode) {
835 BEFORE_GL_CALL;
836 mSymbols.fBlendEquation(mode);
837 AFTER_GL_CALL;
840 void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
841 BEFORE_GL_CALL;
842 mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
843 AFTER_GL_CALL;
846 void fBlendFunc(GLenum sfactor, GLenum dfactor) {
847 BEFORE_GL_CALL;
848 mSymbols.fBlendFunc(sfactor, dfactor);
849 AFTER_GL_CALL;
852 void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB,
853 GLenum sfactorAlpha, GLenum dfactorAlpha) {
854 BEFORE_GL_CALL;
855 mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha,
856 dfactorAlpha);
857 AFTER_GL_CALL;
860 private:
861 void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
862 GLenum usage) {
863 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
864 BEFORE_GL_CALL;
865 mSymbols.fBufferData(target, size, data, usage);
866 OnSyncCall();
867 AFTER_GL_CALL;
868 mHeavyGLCallsSinceLastFlush = true;
871 public:
872 void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
873 GLenum usage) {
874 raw_fBufferData(target, size, data, usage);
876 // bug 744888
877 if (WorkAroundDriverBugs() && !data && Vendor() == GLVendor::NVIDIA) {
878 UniquePtr<char[]> buf = MakeUnique<char[]>(1);
879 buf[0] = 0;
880 fBufferSubData(target, size - 1, 1, buf.get());
884 void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
885 const GLvoid* data) {
886 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
887 BEFORE_GL_CALL;
888 mSymbols.fBufferSubData(target, offset, size, data);
889 AFTER_GL_CALL;
890 mHeavyGLCallsSinceLastFlush = true;
893 private:
894 void raw_fClear(GLbitfield mask) {
895 BEFORE_GL_CALL;
896 mSymbols.fClear(mask);
897 AFTER_GL_CALL;
900 public:
901 void fClear(GLbitfield mask) {
902 BeforeGLDrawCall();
903 raw_fClear(mask);
904 AfterGLDrawCall();
907 void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth,
908 GLint stencil) {
909 BeforeGLDrawCall();
910 BEFORE_GL_CALL;
911 mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
912 AFTER_GL_CALL;
913 AfterGLDrawCall();
916 void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
917 BeforeGLDrawCall();
918 BEFORE_GL_CALL;
919 mSymbols.fClearBufferfv(buffer, drawbuffer, value);
920 AFTER_GL_CALL;
921 AfterGLDrawCall();
924 void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
925 BeforeGLDrawCall();
926 BEFORE_GL_CALL;
927 mSymbols.fClearBufferiv(buffer, drawbuffer, value);
928 AFTER_GL_CALL;
929 AfterGLDrawCall();
932 void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
933 BeforeGLDrawCall();
934 BEFORE_GL_CALL;
935 mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
936 AFTER_GL_CALL;
937 AfterGLDrawCall();
940 void fClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
941 BEFORE_GL_CALL;
942 mSymbols.fClearColor(r, g, b, a);
943 AFTER_GL_CALL;
946 void fClearStencil(GLint s) {
947 BEFORE_GL_CALL;
948 mSymbols.fClearStencil(s);
949 AFTER_GL_CALL;
952 void fClientActiveTexture(GLenum texture) {
953 BEFORE_GL_CALL;
954 mSymbols.fClientActiveTexture(texture);
955 AFTER_GL_CALL;
958 void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue,
959 realGLboolean alpha) {
960 BEFORE_GL_CALL;
961 mSymbols.fColorMask(red, green, blue, alpha);
962 AFTER_GL_CALL;
965 void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
966 GLsizei width, GLsizei height, GLint border,
967 GLsizei imageSize, const GLvoid* pixels) {
968 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
969 BEFORE_GL_CALL;
970 mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height,
971 border, imageSize, pixels);
972 AFTER_GL_CALL;
973 mHeavyGLCallsSinceLastFlush = true;
976 void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
977 GLint yoffset, GLsizei width, GLsizei height,
978 GLenum format, GLsizei imageSize,
979 const GLvoid* pixels) {
980 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
981 BEFORE_GL_CALL;
982 mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
983 height, format, imageSize, pixels);
984 AFTER_GL_CALL;
985 mHeavyGLCallsSinceLastFlush = true;
988 void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
989 GLint x, GLint y, GLsizei width, GLsizei height,
990 GLint border);
992 void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
993 GLint yoffset, GLint x, GLint y, GLsizei width,
994 GLsizei height) {
995 BeforeGLReadCall();
996 raw_fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
997 height);
998 AfterGLReadCall();
1001 void fCullFace(GLenum mode) {
1002 BEFORE_GL_CALL;
1003 mSymbols.fCullFace(mode);
1004 AFTER_GL_CALL;
1007 void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
1008 BEFORE_GL_CALL;
1009 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
1010 mSymbols.fDebugMessageCallback(callback, userParam);
1011 AFTER_GL_CALL;
1014 void fDebugMessageControl(GLenum source, GLenum type, GLenum severity,
1015 GLsizei count, const GLuint* ids,
1016 realGLboolean enabled) {
1017 BEFORE_GL_CALL;
1018 ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
1019 mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
1020 AFTER_GL_CALL;
1023 void fDebugMessageInsert(GLenum source, GLenum type, GLuint id,
1024 GLenum severity, GLsizei length, const GLchar* buf) {
1025 BEFORE_GL_CALL;
1026 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
1027 mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
1028 AFTER_GL_CALL;
1031 void fDetachShader(GLuint program, GLuint shader) {
1032 BEFORE_GL_CALL;
1033 mSymbols.fDetachShader(program, shader);
1034 AFTER_GL_CALL;
1037 void fDepthFunc(GLenum func) {
1038 BEFORE_GL_CALL;
1039 mSymbols.fDepthFunc(func);
1040 AFTER_GL_CALL;
1043 void fDepthMask(realGLboolean flag) {
1044 BEFORE_GL_CALL;
1045 mSymbols.fDepthMask(flag);
1046 AFTER_GL_CALL;
1049 void fDisable(GLenum capability) {
1050 BEFORE_GL_CALL;
1051 mSymbols.fDisable(capability);
1052 AFTER_GL_CALL;
1055 void fDisableClientState(GLenum capability) {
1056 BEFORE_GL_CALL;
1057 mSymbols.fDisableClientState(capability);
1058 AFTER_GL_CALL;
1061 void fDisableVertexAttribArray(GLuint index) {
1062 BEFORE_GL_CALL;
1063 mSymbols.fDisableVertexAttribArray(index);
1064 AFTER_GL_CALL;
1067 void fDrawBuffer(GLenum mode) {
1068 BEFORE_GL_CALL;
1069 mSymbols.fDrawBuffer(mode);
1070 AFTER_GL_CALL;
1073 private:
1074 void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1075 BEFORE_GL_CALL;
1076 mSymbols.fDrawArrays(mode, first, count);
1077 AFTER_GL_CALL;
1080 void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type,
1081 const GLvoid* indices) {
1082 BEFORE_GL_CALL;
1083 mSymbols.fDrawElements(mode, count, type, indices);
1084 AFTER_GL_CALL;
1087 public:
1088 void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1089 BeforeGLDrawCall();
1090 raw_fDrawArrays(mode, first, count);
1091 AfterGLDrawCall();
1094 void fDrawElements(GLenum mode, GLsizei count, GLenum type,
1095 const GLvoid* indices) {
1096 BeforeGLDrawCall();
1097 raw_fDrawElements(mode, count, type, indices);
1098 AfterGLDrawCall();
1101 void fEnable(GLenum capability) {
1102 BEFORE_GL_CALL;
1103 mSymbols.fEnable(capability);
1104 AFTER_GL_CALL;
1107 void fEnableClientState(GLenum capability) {
1108 BEFORE_GL_CALL;
1109 mSymbols.fEnableClientState(capability);
1110 AFTER_GL_CALL;
1113 void fEnableVertexAttribArray(GLuint index) {
1114 BEFORE_GL_CALL;
1115 mSymbols.fEnableVertexAttribArray(index);
1116 AFTER_GL_CALL;
1119 void fEndQuery(GLenum target) {
1120 BEFORE_GL_CALL;
1121 ASSERT_SYMBOL_PRESENT(fEndQuery);
1122 mSymbols.fEndQuery(target);
1123 AFTER_GL_CALL;
1126 void fFinish() {
1127 BEFORE_GL_CALL;
1128 mSymbols.fFinish();
1129 OnSyncCall();
1130 AFTER_GL_CALL;
1131 mHeavyGLCallsSinceLastFlush = false;
1134 void fFlush() {
1135 BEFORE_GL_CALL;
1136 mSymbols.fFlush();
1137 AFTER_GL_CALL;
1138 mHeavyGLCallsSinceLastFlush = false;
1141 void fFrontFace(GLenum face) {
1142 BEFORE_GL_CALL;
1143 mSymbols.fFrontFace(face);
1144 AFTER_GL_CALL;
1147 void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength,
1148 GLsizei* length, GLint* size, GLenum* type,
1149 GLchar* name) {
1150 BEFORE_GL_CALL;
1151 mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type,
1152 name);
1153 OnSyncCall();
1154 AFTER_GL_CALL;
1157 void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength,
1158 GLsizei* length, GLint* size, GLenum* type,
1159 GLchar* name) {
1160 BEFORE_GL_CALL;
1161 mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type,
1162 name);
1163 OnSyncCall();
1164 AFTER_GL_CALL;
1167 void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count,
1168 GLuint* shaders) {
1169 BEFORE_GL_CALL;
1170 mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
1171 OnSyncCall();
1172 AFTER_GL_CALL;
1175 GLint fGetAttribLocation(GLuint program, const GLchar* name) {
1176 GLint retval = 0;
1177 BEFORE_GL_CALL;
1178 retval = mSymbols.fGetAttribLocation(program, name);
1179 OnSyncCall();
1180 AFTER_GL_CALL;
1181 return retval;
1184 private:
1185 void raw_fGetIntegerv(GLenum pname, GLint* params) const {
1186 BEFORE_GL_CALL;
1187 mSymbols.fGetIntegerv(pname, params);
1188 OnSyncCall();
1189 AFTER_GL_CALL;
1192 public:
1193 void fGetIntegerv(GLenum pname, GLint* params) const;
1195 template <typename T>
1196 void GetInt(const GLenum pname, T* const params) const {
1197 static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
1198 fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
1201 void GetUIntegerv(GLenum pname, GLuint* params) const {
1202 GetInt(pname, params);
1205 template <typename T>
1206 T GetIntAs(GLenum pname) const {
1207 static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
1208 T ret = 0;
1209 fGetIntegerv(pname, (GLint*)&ret);
1210 return ret;
1213 void fGetFloatv(GLenum pname, GLfloat* params) const {
1214 BEFORE_GL_CALL;
1215 mSymbols.fGetFloatv(pname, params);
1216 OnSyncCall();
1217 AFTER_GL_CALL;
1220 void fGetBooleanv(GLenum pname, realGLboolean* params) const {
1221 BEFORE_GL_CALL;
1222 mSymbols.fGetBooleanv(pname, params);
1223 OnSyncCall();
1224 AFTER_GL_CALL;
1227 void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
1228 BEFORE_GL_CALL;
1229 mSymbols.fGetBufferParameteriv(target, pname, params);
1230 OnSyncCall();
1231 AFTER_GL_CALL;
1234 GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources,
1235 GLenum* types, GLuint* ids, GLenum* severities,
1236 GLsizei* lengths, GLchar* messageLog) {
1237 GLuint ret = 0;
1238 BEFORE_GL_CALL;
1239 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
1240 ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids,
1241 severities, lengths, messageLog);
1242 OnSyncCall();
1243 AFTER_GL_CALL;
1244 return ret;
1247 void fGetPointerv(GLenum pname, GLvoid** params) {
1248 BEFORE_GL_CALL;
1249 ASSERT_SYMBOL_PRESENT(fGetPointerv);
1250 mSymbols.fGetPointerv(pname, params);
1251 OnSyncCall();
1252 AFTER_GL_CALL;
1255 void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize,
1256 GLsizei* length, GLchar* label) {
1257 BEFORE_GL_CALL;
1258 ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
1259 mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
1260 OnSyncCall();
1261 AFTER_GL_CALL;
1264 void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length,
1265 GLchar* label) {
1266 BEFORE_GL_CALL;
1267 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
1268 mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
1269 OnSyncCall();
1270 AFTER_GL_CALL;
1273 void fGenerateMipmap(GLenum target) {
1274 BEFORE_GL_CALL;
1275 mSymbols.fGenerateMipmap(target);
1276 AFTER_GL_CALL;
1279 void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
1280 BEFORE_GL_CALL;
1281 mSymbols.fGetProgramiv(program, pname, param);
1282 OnSyncCall();
1283 AFTER_GL_CALL;
1286 void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length,
1287 GLchar* infoLog) {
1288 BEFORE_GL_CALL;
1289 mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
1290 OnSyncCall();
1291 AFTER_GL_CALL;
1294 void fTexParameteri(GLenum target, GLenum pname, GLint param) {
1295 BEFORE_GL_CALL;
1296 mSymbols.fTexParameteri(target, pname, param);
1297 AFTER_GL_CALL;
1300 void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
1301 BEFORE_GL_CALL;
1302 mSymbols.fTexParameteriv(target, pname, params);
1303 AFTER_GL_CALL;
1306 void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
1307 BEFORE_GL_CALL;
1308 mSymbols.fTexParameterf(target, pname, param);
1309 AFTER_GL_CALL;
1312 const GLubyte* fGetString(GLenum name) {
1313 const GLubyte* result = nullptr;
1314 BEFORE_GL_CALL;
1315 result = mSymbols.fGetString(name);
1316 OnSyncCall();
1317 AFTER_GL_CALL;
1318 return result;
1321 void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type,
1322 GLvoid* img) {
1323 BEFORE_GL_CALL;
1324 ASSERT_SYMBOL_PRESENT(fGetTexImage);
1325 mSymbols.fGetTexImage(target, level, format, type, img);
1326 OnSyncCall();
1327 AFTER_GL_CALL;
1330 void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname,
1331 GLint* params) {
1332 BEFORE_GL_CALL;
1333 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
1334 mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
1335 OnSyncCall();
1336 AFTER_GL_CALL;
1339 void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
1340 BEFORE_GL_CALL;
1341 mSymbols.fGetTexParameterfv(target, pname, params);
1342 OnSyncCall();
1343 AFTER_GL_CALL;
1346 void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
1347 BEFORE_GL_CALL;
1348 mSymbols.fGetTexParameteriv(target, pname, params);
1349 OnSyncCall();
1350 AFTER_GL_CALL;
1353 void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
1354 BEFORE_GL_CALL;
1355 mSymbols.fGetUniformfv(program, location, params);
1356 OnSyncCall();
1357 AFTER_GL_CALL;
1360 void fGetUniformiv(GLuint program, GLint location, GLint* params) {
1361 BEFORE_GL_CALL;
1362 mSymbols.fGetUniformiv(program, location, params);
1363 OnSyncCall();
1364 AFTER_GL_CALL;
1367 void fGetUniformuiv(GLuint program, GLint location, GLuint* params) {
1368 BEFORE_GL_CALL;
1369 ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
1370 mSymbols.fGetUniformuiv(program, location, params);
1371 OnSyncCall();
1372 AFTER_GL_CALL;
1375 GLint fGetUniformLocation(GLuint programObj, const GLchar* name) {
1376 GLint retval = 0;
1377 BEFORE_GL_CALL;
1378 retval = mSymbols.fGetUniformLocation(programObj, name);
1379 OnSyncCall();
1380 AFTER_GL_CALL;
1381 return retval;
1384 void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
1385 BEFORE_GL_CALL;
1386 mSymbols.fGetVertexAttribfv(index, pname, retval);
1387 OnSyncCall();
1388 AFTER_GL_CALL;
1391 void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
1392 BEFORE_GL_CALL;
1393 mSymbols.fGetVertexAttribiv(index, pname, retval);
1394 OnSyncCall();
1395 AFTER_GL_CALL;
1398 void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
1399 BEFORE_GL_CALL;
1400 mSymbols.fGetVertexAttribPointerv(index, pname, retval);
1401 OnSyncCall();
1402 AFTER_GL_CALL;
1405 void fHint(GLenum target, GLenum mode) {
1406 BEFORE_GL_CALL;
1407 mSymbols.fHint(target, mode);
1408 AFTER_GL_CALL;
1411 realGLboolean fIsBuffer(GLuint buffer) {
1412 realGLboolean retval = false;
1413 BEFORE_GL_CALL;
1414 retval = mSymbols.fIsBuffer(buffer);
1415 OnSyncCall();
1416 AFTER_GL_CALL;
1417 return retval;
1420 realGLboolean fIsEnabled(GLenum capability) {
1421 realGLboolean retval = false;
1422 BEFORE_GL_CALL;
1423 retval = mSymbols.fIsEnabled(capability);
1424 AFTER_GL_CALL;
1425 return retval;
1428 void SetEnabled(const GLenum cap, const bool val) {
1429 if (val) {
1430 fEnable(cap);
1431 } else {
1432 fDisable(cap);
1436 bool PushEnabled(const GLenum cap, const bool newVal) {
1437 const bool oldVal = fIsEnabled(cap);
1438 if (oldVal != newVal) {
1439 SetEnabled(cap, newVal);
1441 return oldVal;
1444 realGLboolean fIsProgram(GLuint program) {
1445 realGLboolean retval = false;
1446 BEFORE_GL_CALL;
1447 retval = mSymbols.fIsProgram(program);
1448 AFTER_GL_CALL;
1449 return retval;
1452 realGLboolean fIsShader(GLuint shader) {
1453 realGLboolean retval = false;
1454 BEFORE_GL_CALL;
1455 retval = mSymbols.fIsShader(shader);
1456 AFTER_GL_CALL;
1457 return retval;
1460 realGLboolean fIsTexture(GLuint texture) {
1461 realGLboolean retval = false;
1462 BEFORE_GL_CALL;
1463 retval = mSymbols.fIsTexture(texture);
1464 AFTER_GL_CALL;
1465 return retval;
1468 void fLineWidth(GLfloat width) {
1469 BEFORE_GL_CALL;
1470 mSymbols.fLineWidth(width);
1471 AFTER_GL_CALL;
1474 void fLinkProgram(GLuint program) {
1475 BEFORE_GL_CALL;
1476 mSymbols.fLinkProgram(program);
1477 AFTER_GL_CALL;
1480 void fObjectLabel(GLenum identifier, GLuint name, GLsizei length,
1481 const GLchar* label) {
1482 BEFORE_GL_CALL;
1483 ASSERT_SYMBOL_PRESENT(fObjectLabel);
1484 mSymbols.fObjectLabel(identifier, name, length, label);
1485 AFTER_GL_CALL;
1488 void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
1489 BEFORE_GL_CALL;
1490 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
1491 mSymbols.fObjectPtrLabel(ptr, length, label);
1492 AFTER_GL_CALL;
1495 void fLoadIdentity() {
1496 BEFORE_GL_CALL;
1497 mSymbols.fLoadIdentity();
1498 AFTER_GL_CALL;
1501 void fLoadMatrixf(const GLfloat* matrix) {
1502 BEFORE_GL_CALL;
1503 mSymbols.fLoadMatrixf(matrix);
1504 AFTER_GL_CALL;
1507 void fMatrixMode(GLenum mode) {
1508 BEFORE_GL_CALL;
1509 mSymbols.fMatrixMode(mode);
1510 AFTER_GL_CALL;
1513 void fPixelStorei(GLenum pname, GLint param) {
1514 BEFORE_GL_CALL;
1515 mSymbols.fPixelStorei(pname, param);
1516 AFTER_GL_CALL;
1519 void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid* pointer) {
1520 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer);
1521 BEFORE_GL_CALL;
1522 mSymbols.fTextureRangeAPPLE(target, length, pointer);
1523 AFTER_GL_CALL;
1526 void fPointParameterf(GLenum pname, GLfloat param) {
1527 BEFORE_GL_CALL;
1528 mSymbols.fPointParameterf(pname, param);
1529 AFTER_GL_CALL;
1532 void fPolygonMode(GLenum face, GLenum mode) {
1533 BEFORE_GL_CALL;
1534 mSymbols.fPolygonMode(face, mode);
1535 AFTER_GL_CALL;
1538 void fPolygonOffset(GLfloat factor, GLfloat bias) {
1539 BEFORE_GL_CALL;
1540 mSymbols.fPolygonOffset(factor, bias);
1541 AFTER_GL_CALL;
1544 void fPopDebugGroup() {
1545 BEFORE_GL_CALL;
1546 ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
1547 mSymbols.fPopDebugGroup();
1548 AFTER_GL_CALL;
1551 void fPushDebugGroup(GLenum source, GLuint id, GLsizei length,
1552 const GLchar* message) {
1553 BEFORE_GL_CALL;
1554 ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
1555 mSymbols.fPushDebugGroup(source, id, length, message);
1556 AFTER_GL_CALL;
1559 void fReadBuffer(GLenum mode) {
1560 BEFORE_GL_CALL;
1561 mSymbols.fReadBuffer(mode);
1562 AFTER_GL_CALL;
1565 void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1566 GLenum format, GLenum type, GLvoid* pixels) {
1567 BEFORE_GL_CALL;
1568 mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
1569 OnSyncCall();
1570 AFTER_GL_CALL;
1571 mHeavyGLCallsSinceLastFlush = true;
1574 void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1575 GLenum format, GLenum type, GLvoid* pixels);
1577 public:
1578 void fSampleCoverage(GLclampf value, realGLboolean invert) {
1579 BEFORE_GL_CALL;
1580 mSymbols.fSampleCoverage(value, invert);
1581 AFTER_GL_CALL;
1584 void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1585 if (mScissorRect[0] == x && mScissorRect[1] == y &&
1586 mScissorRect[2] == width && mScissorRect[3] == height) {
1587 return;
1589 mScissorRect[0] = x;
1590 mScissorRect[1] = y;
1591 mScissorRect[2] = width;
1592 mScissorRect[3] = height;
1593 BEFORE_GL_CALL;
1594 mSymbols.fScissor(x, y, width, height);
1595 AFTER_GL_CALL;
1598 void fStencilFunc(GLenum func, GLint reference, GLuint mask) {
1599 BEFORE_GL_CALL;
1600 mSymbols.fStencilFunc(func, reference, mask);
1601 AFTER_GL_CALL;
1604 void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint reference,
1605 GLuint mask) {
1606 BEFORE_GL_CALL;
1607 mSymbols.fStencilFuncSeparate(frontfunc, backfunc, reference, mask);
1608 AFTER_GL_CALL;
1611 void fStencilMask(GLuint mask) {
1612 BEFORE_GL_CALL;
1613 mSymbols.fStencilMask(mask);
1614 AFTER_GL_CALL;
1617 void fStencilMaskSeparate(GLenum face, GLuint mask) {
1618 BEFORE_GL_CALL;
1619 mSymbols.fStencilMaskSeparate(face, mask);
1620 AFTER_GL_CALL;
1623 void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
1624 BEFORE_GL_CALL;
1625 mSymbols.fStencilOp(fail, zfail, zpass);
1626 AFTER_GL_CALL;
1629 void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail,
1630 GLenum dppass) {
1631 BEFORE_GL_CALL;
1632 mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
1633 AFTER_GL_CALL;
1636 void fTexGeni(GLenum coord, GLenum pname, GLint param) {
1637 BEFORE_GL_CALL;
1638 mSymbols.fTexGeni(coord, pname, param);
1639 AFTER_GL_CALL;
1642 void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
1643 BEFORE_GL_CALL;
1644 mSymbols.fTexGenf(coord, pname, param);
1645 AFTER_GL_CALL;
1648 void fTexGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1649 BEFORE_GL_CALL;
1650 mSymbols.fTexGenfv(coord, pname, params);
1651 AFTER_GL_CALL;
1654 private:
1655 void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat,
1656 GLsizei width, GLsizei height, GLint border,
1657 GLenum format, GLenum type, const GLvoid* pixels) {
1658 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1659 BEFORE_GL_CALL;
1660 mSymbols.fTexImage2D(target, level, internalformat, width, height, border,
1661 format, type, pixels);
1662 AFTER_GL_CALL;
1663 mHeavyGLCallsSinceLastFlush = true;
1666 public:
1667 void fTexImage2D(GLenum target, GLint level, GLint internalformat,
1668 GLsizei width, GLsizei height, GLint border, GLenum format,
1669 GLenum type, const GLvoid* pixels);
1671 void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
1672 GLsizei width, GLsizei height, GLenum format, GLenum type,
1673 const GLvoid* pixels) {
1674 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1675 BEFORE_GL_CALL;
1676 mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height,
1677 format, type, pixels);
1678 AFTER_GL_CALL;
1679 mHeavyGLCallsSinceLastFlush = true;
1682 void fUniform1f(GLint location, GLfloat v0) {
1683 BEFORE_GL_CALL;
1684 mSymbols.fUniform1f(location, v0);
1685 AFTER_GL_CALL;
1688 void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
1689 BEFORE_GL_CALL;
1690 mSymbols.fUniform1fv(location, count, value);
1691 AFTER_GL_CALL;
1694 void fUniform1i(GLint location, GLint v0) {
1695 BEFORE_GL_CALL;
1696 mSymbols.fUniform1i(location, v0);
1697 AFTER_GL_CALL;
1700 void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
1701 BEFORE_GL_CALL;
1702 mSymbols.fUniform1iv(location, count, value);
1703 AFTER_GL_CALL;
1706 void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
1707 BEFORE_GL_CALL;
1708 mSymbols.fUniform2f(location, v0, v1);
1709 AFTER_GL_CALL;
1712 void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
1713 BEFORE_GL_CALL;
1714 mSymbols.fUniform2fv(location, count, value);
1715 AFTER_GL_CALL;
1718 void fUniform2i(GLint location, GLint v0, GLint v1) {
1719 BEFORE_GL_CALL;
1720 mSymbols.fUniform2i(location, v0, v1);
1721 AFTER_GL_CALL;
1724 void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
1725 BEFORE_GL_CALL;
1726 mSymbols.fUniform2iv(location, count, value);
1727 AFTER_GL_CALL;
1730 void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
1731 BEFORE_GL_CALL;
1732 mSymbols.fUniform3f(location, v0, v1, v2);
1733 AFTER_GL_CALL;
1736 void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
1737 BEFORE_GL_CALL;
1738 mSymbols.fUniform3fv(location, count, value);
1739 AFTER_GL_CALL;
1742 void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
1743 BEFORE_GL_CALL;
1744 mSymbols.fUniform3i(location, v0, v1, v2);
1745 AFTER_GL_CALL;
1748 void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
1749 BEFORE_GL_CALL;
1750 mSymbols.fUniform3iv(location, count, value);
1751 AFTER_GL_CALL;
1754 void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
1755 GLfloat v3) {
1756 BEFORE_GL_CALL;
1757 mSymbols.fUniform4f(location, v0, v1, v2, v3);
1758 AFTER_GL_CALL;
1761 void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
1762 BEFORE_GL_CALL;
1763 mSymbols.fUniform4fv(location, count, value);
1764 AFTER_GL_CALL;
1767 void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
1768 BEFORE_GL_CALL;
1769 mSymbols.fUniform4i(location, v0, v1, v2, v3);
1770 AFTER_GL_CALL;
1773 void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
1774 BEFORE_GL_CALL;
1775 mSymbols.fUniform4iv(location, count, value);
1776 AFTER_GL_CALL;
1779 void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose,
1780 const GLfloat* value) {
1781 BEFORE_GL_CALL;
1782 mSymbols.fUniformMatrix2fv(location, count, transpose, value);
1783 AFTER_GL_CALL;
1786 void fUniformMatrix2x3fv(GLint location, GLsizei count,
1787 realGLboolean transpose, const GLfloat* value) {
1788 BEFORE_GL_CALL;
1789 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv);
1790 mSymbols.fUniformMatrix2x3fv(location, count, transpose, value);
1791 AFTER_GL_CALL;
1794 void fUniformMatrix2x4fv(GLint location, GLsizei count,
1795 realGLboolean transpose, const GLfloat* value) {
1796 BEFORE_GL_CALL;
1797 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv);
1798 mSymbols.fUniformMatrix2x4fv(location, count, transpose, value);
1799 AFTER_GL_CALL;
1802 void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose,
1803 const GLfloat* value) {
1804 BEFORE_GL_CALL;
1805 mSymbols.fUniformMatrix3fv(location, count, transpose, value);
1806 AFTER_GL_CALL;
1809 void fUniformMatrix3x2fv(GLint location, GLsizei count,
1810 realGLboolean transpose, const GLfloat* value) {
1811 BEFORE_GL_CALL;
1812 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv);
1813 mSymbols.fUniformMatrix3x2fv(location, count, transpose, value);
1814 AFTER_GL_CALL;
1817 void fUniformMatrix3x4fv(GLint location, GLsizei count,
1818 realGLboolean transpose, const GLfloat* value) {
1819 BEFORE_GL_CALL;
1820 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv);
1821 mSymbols.fUniformMatrix3x4fv(location, count, transpose, value);
1822 AFTER_GL_CALL;
1825 void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose,
1826 const GLfloat* value) {
1827 BEFORE_GL_CALL;
1828 mSymbols.fUniformMatrix4fv(location, count, transpose, value);
1829 AFTER_GL_CALL;
1832 void fUniformMatrix4x2fv(GLint location, GLsizei count,
1833 realGLboolean transpose, const GLfloat* value) {
1834 BEFORE_GL_CALL;
1835 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv);
1836 mSymbols.fUniformMatrix4x2fv(location, count, transpose, value);
1837 AFTER_GL_CALL;
1840 void fUniformMatrix4x3fv(GLint location, GLsizei count,
1841 realGLboolean transpose, const GLfloat* value) {
1842 BEFORE_GL_CALL;
1843 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv);
1844 mSymbols.fUniformMatrix4x3fv(location, count, transpose, value);
1845 AFTER_GL_CALL;
1848 void fUseProgram(GLuint program) {
1849 BEFORE_GL_CALL;
1850 mSymbols.fUseProgram(program);
1851 AFTER_GL_CALL;
1854 void fValidateProgram(GLuint program) {
1855 BEFORE_GL_CALL;
1856 mSymbols.fValidateProgram(program);
1857 AFTER_GL_CALL;
1860 void fVertexAttribPointer(GLuint index, GLint size, GLenum type,
1861 realGLboolean normalized, GLsizei stride,
1862 const GLvoid* pointer) {
1863 BEFORE_GL_CALL;
1864 mSymbols.fVertexAttribPointer(index, size, type, normalized, stride,
1865 pointer);
1866 AFTER_GL_CALL;
1869 void fVertexAttrib1f(GLuint index, GLfloat x) {
1870 BEFORE_GL_CALL;
1871 mSymbols.fVertexAttrib1f(index, x);
1872 AFTER_GL_CALL;
1875 void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1876 BEFORE_GL_CALL;
1877 mSymbols.fVertexAttrib2f(index, x, y);
1878 AFTER_GL_CALL;
1881 void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1882 BEFORE_GL_CALL;
1883 mSymbols.fVertexAttrib3f(index, x, y, z);
1884 AFTER_GL_CALL;
1887 void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z,
1888 GLfloat w) {
1889 BEFORE_GL_CALL;
1890 mSymbols.fVertexAttrib4f(index, x, y, z, w);
1891 AFTER_GL_CALL;
1894 void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
1895 BEFORE_GL_CALL;
1896 mSymbols.fVertexAttrib1fv(index, v);
1897 AFTER_GL_CALL;
1900 void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
1901 BEFORE_GL_CALL;
1902 mSymbols.fVertexAttrib2fv(index, v);
1903 AFTER_GL_CALL;
1906 void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
1907 BEFORE_GL_CALL;
1908 mSymbols.fVertexAttrib3fv(index, v);
1909 AFTER_GL_CALL;
1912 void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
1913 BEFORE_GL_CALL;
1914 mSymbols.fVertexAttrib4fv(index, v);
1915 AFTER_GL_CALL;
1918 void fVertexPointer(GLint size, GLenum type, GLsizei stride,
1919 const GLvoid* pointer) {
1920 BEFORE_GL_CALL;
1921 mSymbols.fVertexPointer(size, type, stride, pointer);
1922 AFTER_GL_CALL;
1925 void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
1926 if (mViewportRect[0] == x && mViewportRect[1] == y &&
1927 mViewportRect[2] == width && mViewportRect[3] == height) {
1928 return;
1930 mViewportRect[0] = x;
1931 mViewportRect[1] = y;
1932 mViewportRect[2] = width;
1933 mViewportRect[3] = height;
1934 BEFORE_GL_CALL;
1935 mSymbols.fViewport(x, y, width, height);
1936 AFTER_GL_CALL;
1939 void fCompileShader(GLuint shader) {
1940 BEFORE_GL_CALL;
1941 mSymbols.fCompileShader(shader);
1942 AFTER_GL_CALL;
1945 private:
1946 friend class SharedSurface_IOSurface;
1948 void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
1949 GLint x, GLint y, GLsizei width, GLsizei height,
1950 GLint border) {
1951 BEFORE_GL_CALL;
1952 mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height,
1953 border);
1954 AFTER_GL_CALL;
1957 void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
1958 GLint yoffset, GLint x, GLint y, GLsizei width,
1959 GLsizei height) {
1960 BEFORE_GL_CALL;
1961 mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
1962 height);
1963 AFTER_GL_CALL;
1966 public:
1967 void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
1968 BEFORE_GL_CALL;
1969 mSymbols.fGetShaderiv(shader, pname, param);
1970 OnSyncCall();
1971 AFTER_GL_CALL;
1974 void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length,
1975 GLchar* infoLog) {
1976 BEFORE_GL_CALL;
1977 mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
1978 OnSyncCall();
1979 AFTER_GL_CALL;
1982 private:
1983 void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1984 GLint* range, GLint* precision) {
1985 MOZ_ASSERT(IsGLES());
1987 BEFORE_GL_CALL;
1988 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
1989 mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range,
1990 precision);
1991 OnSyncCall();
1992 AFTER_GL_CALL;
1995 public:
1996 void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
1997 GLint* range, GLint* precision) {
1998 if (IsGLES()) {
1999 raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range,
2000 precision);
2001 } else {
2002 // Fall back to automatic values because almost all desktop hardware
2003 // supports the OpenGL standard precisions.
2004 GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range,
2005 precision);
2009 void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length,
2010 GLchar* source) {
2011 BEFORE_GL_CALL;
2012 mSymbols.fGetShaderSource(obj, maxLength, length, source);
2013 OnSyncCall();
2014 AFTER_GL_CALL;
2017 void fShaderSource(GLuint shader, GLsizei count, const GLchar* const* strings,
2018 const GLint* lengths) {
2019 BEFORE_GL_CALL;
2020 mSymbols.fShaderSource(shader, count, strings, lengths);
2021 AFTER_GL_CALL;
2024 private:
2025 mutable GLuint mCachedDrawFb = 0;
2026 mutable GLuint mCachedReadFb = 0;
2028 public:
2029 bool mElideDuplicateBindFramebuffers = false;
2031 void fBindFramebuffer(const GLenum target, const GLuint fb) const {
2032 if (mElideDuplicateBindFramebuffers) {
2033 MOZ_ASSERT(mCachedDrawFb ==
2034 GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING));
2035 MOZ_ASSERT(mCachedReadFb ==
2036 GetIntAs<GLuint>(LOCAL_GL_READ_FRAMEBUFFER_BINDING));
2038 switch (target) {
2039 case LOCAL_GL_FRAMEBUFFER:
2040 if (mCachedDrawFb == fb && mCachedReadFb == fb) return;
2041 break;
2042 case LOCAL_GL_DRAW_FRAMEBUFFER:
2043 if (mCachedDrawFb == fb) return;
2044 break;
2045 case LOCAL_GL_READ_FRAMEBUFFER:
2046 if (mCachedReadFb == fb) return;
2047 break;
2051 BEFORE_GL_CALL;
2052 mSymbols.fBindFramebuffer(target, fb);
2053 AFTER_GL_CALL;
2055 switch (target) {
2056 case LOCAL_GL_FRAMEBUFFER:
2057 mCachedDrawFb = fb;
2058 mCachedReadFb = fb;
2059 break;
2060 case LOCAL_GL_DRAW_FRAMEBUFFER:
2061 mCachedDrawFb = fb;
2062 break;
2063 case LOCAL_GL_READ_FRAMEBUFFER:
2064 mCachedReadFb = fb;
2065 break;
2069 void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
2070 BEFORE_GL_CALL;
2071 mSymbols.fBindRenderbuffer(target, renderbuffer);
2072 AFTER_GL_CALL;
2075 GLenum fCheckFramebufferStatus(GLenum target) {
2076 GLenum retval = 0;
2077 BEFORE_GL_CALL;
2078 retval = mSymbols.fCheckFramebufferStatus(target);
2079 OnSyncCall();
2080 AFTER_GL_CALL;
2081 return retval;
2084 void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint,
2085 GLenum renderbufferTarget,
2086 GLuint renderbuffer) {
2087 BEFORE_GL_CALL;
2088 mSymbols.fFramebufferRenderbuffer(target, attachmentPoint,
2089 renderbufferTarget, renderbuffer);
2090 AFTER_GL_CALL;
2093 void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint,
2094 GLenum textureTarget, GLuint texture,
2095 GLint level) {
2096 BEFORE_GL_CALL;
2097 mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget,
2098 texture, level);
2099 AFTER_GL_CALL;
2102 void fFramebufferTextureLayer(GLenum target, GLenum attachment,
2103 GLuint texture, GLint level, GLint layer) {
2104 BEFORE_GL_CALL;
2105 ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
2106 mSymbols.fFramebufferTextureLayer(target, attachment, texture, level,
2107 layer);
2108 AFTER_GL_CALL;
2111 void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
2112 GLenum pname, GLint* value) {
2113 BEFORE_GL_CALL;
2114 mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname,
2115 value);
2116 OnSyncCall();
2117 AFTER_GL_CALL;
2120 void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
2121 BEFORE_GL_CALL;
2122 mSymbols.fGetRenderbufferParameteriv(target, pname, value);
2123 OnSyncCall();
2124 AFTER_GL_CALL;
2127 realGLboolean fIsFramebuffer(GLuint framebuffer) {
2128 realGLboolean retval = false;
2129 BEFORE_GL_CALL;
2130 retval = mSymbols.fIsFramebuffer(framebuffer);
2131 OnSyncCall();
2132 AFTER_GL_CALL;
2133 return retval;
2136 public:
2137 realGLboolean fIsRenderbuffer(GLuint renderbuffer) {
2138 realGLboolean retval = false;
2139 BEFORE_GL_CALL;
2140 retval = mSymbols.fIsRenderbuffer(renderbuffer);
2141 OnSyncCall();
2142 AFTER_GL_CALL;
2143 return retval;
2146 void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width,
2147 GLsizei height) {
2148 BEFORE_GL_CALL;
2149 mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
2150 AFTER_GL_CALL;
2153 private:
2154 void raw_fDepthRange(GLclampf a, GLclampf b) {
2155 MOZ_ASSERT(!IsGLES());
2157 BEFORE_GL_CALL;
2158 ASSERT_SYMBOL_PRESENT(fDepthRange);
2159 mSymbols.fDepthRange(a, b);
2160 AFTER_GL_CALL;
2163 void raw_fDepthRangef(GLclampf a, GLclampf b) {
2164 MOZ_ASSERT(IsGLES());
2166 BEFORE_GL_CALL;
2167 ASSERT_SYMBOL_PRESENT(fDepthRangef);
2168 mSymbols.fDepthRangef(a, b);
2169 AFTER_GL_CALL;
2172 void raw_fClearDepth(GLclampf v) {
2173 MOZ_ASSERT(!IsGLES());
2175 BEFORE_GL_CALL;
2176 ASSERT_SYMBOL_PRESENT(fClearDepth);
2177 mSymbols.fClearDepth(v);
2178 AFTER_GL_CALL;
2181 void raw_fClearDepthf(GLclampf v) {
2182 MOZ_ASSERT(IsGLES());
2184 BEFORE_GL_CALL;
2185 ASSERT_SYMBOL_PRESENT(fClearDepthf);
2186 mSymbols.fClearDepthf(v);
2187 AFTER_GL_CALL;
2190 public:
2191 void fDepthRange(GLclampf a, GLclampf b) {
2192 if (IsGLES()) {
2193 raw_fDepthRangef(a, b);
2194 } else {
2195 raw_fDepthRange(a, b);
2199 void fClearDepth(GLclampf v) {
2200 if (IsGLES()) {
2201 raw_fClearDepthf(v);
2202 } else {
2203 raw_fClearDepth(v);
2207 void* fMapBuffer(GLenum target, GLenum access) {
2208 void* ret = nullptr;
2209 BEFORE_GL_CALL;
2210 ASSERT_SYMBOL_PRESENT(fMapBuffer);
2211 ret = mSymbols.fMapBuffer(target, access);
2212 OnSyncCall();
2213 AFTER_GL_CALL;
2214 return ret;
2217 realGLboolean fUnmapBuffer(GLenum target) {
2218 realGLboolean ret = false;
2219 BEFORE_GL_CALL;
2220 ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
2221 ret = mSymbols.fUnmapBuffer(target);
2222 AFTER_GL_CALL;
2223 return ret;
2226 private:
2227 GLuint raw_fCreateProgram() {
2228 GLuint ret = 0;
2229 BEFORE_GL_CALL;
2230 ret = mSymbols.fCreateProgram();
2231 AFTER_GL_CALL;
2232 return ret;
2235 GLuint raw_fCreateShader(GLenum t) {
2236 GLuint ret = 0;
2237 BEFORE_GL_CALL;
2238 ret = mSymbols.fCreateShader(t);
2239 AFTER_GL_CALL;
2240 return ret;
2243 void raw_fGenBuffers(GLsizei n, GLuint* names) {
2244 BEFORE_GL_CALL;
2245 mSymbols.fGenBuffers(n, names);
2246 OnSyncCall();
2247 AFTER_GL_CALL;
2250 void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
2251 BEFORE_GL_CALL;
2252 mSymbols.fGenFramebuffers(n, names);
2253 OnSyncCall();
2254 AFTER_GL_CALL;
2257 void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
2258 BEFORE_GL_CALL;
2259 mSymbols.fGenRenderbuffers(n, names);
2260 OnSyncCall();
2261 AFTER_GL_CALL;
2264 void raw_fGenTextures(GLsizei n, GLuint* names) {
2265 BEFORE_GL_CALL;
2266 mSymbols.fGenTextures(n, names);
2267 OnSyncCall();
2268 AFTER_GL_CALL;
2271 public:
2272 GLuint fCreateProgram() {
2273 GLuint ret = raw_fCreateProgram();
2274 TRACKING_CONTEXT(CreatedProgram(this, ret));
2275 return ret;
2278 GLuint fCreateShader(GLenum t) {
2279 GLuint ret = raw_fCreateShader(t);
2280 TRACKING_CONTEXT(CreatedShader(this, ret));
2281 return ret;
2284 void fGenBuffers(GLsizei n, GLuint* names) {
2285 raw_fGenBuffers(n, names);
2286 TRACKING_CONTEXT(CreatedBuffers(this, n, names));
2289 void fGenFramebuffers(GLsizei n, GLuint* names) {
2290 raw_fGenFramebuffers(n, names);
2291 TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
2294 void fGenRenderbuffers(GLsizei n, GLuint* names) {
2295 raw_fGenRenderbuffers(n, names);
2296 TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
2299 void fGenTextures(GLsizei n, GLuint* names) {
2300 raw_fGenTextures(n, names);
2301 TRACKING_CONTEXT(CreatedTextures(this, n, names));
2304 private:
2305 void raw_fDeleteProgram(GLuint program) {
2306 BEFORE_GL_CALL;
2307 mSymbols.fDeleteProgram(program);
2308 AFTER_GL_CALL;
2311 void raw_fDeleteShader(GLuint shader) {
2312 BEFORE_GL_CALL;
2313 mSymbols.fDeleteShader(shader);
2314 AFTER_GL_CALL;
2317 void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
2318 BEFORE_GL_CALL;
2319 mSymbols.fDeleteBuffers(n, names);
2320 AFTER_GL_CALL;
2323 void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2324 BEFORE_GL_CALL;
2325 mSymbols.fDeleteFramebuffers(n, names);
2326 AFTER_GL_CALL;
2328 for (const auto i : IntegerRange(n)) {
2329 const auto fb = names[i];
2330 if (mCachedDrawFb == fb) {
2331 mCachedDrawFb = 0;
2333 if (mCachedReadFb == fb) {
2334 mCachedReadFb = 0;
2339 void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2340 BEFORE_GL_CALL;
2341 mSymbols.fDeleteRenderbuffers(n, names);
2342 AFTER_GL_CALL;
2345 void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
2346 BEFORE_GL_CALL;
2347 mSymbols.fDeleteTextures(n, names);
2348 AFTER_GL_CALL;
2351 public:
2352 void fDeleteProgram(GLuint program) {
2353 raw_fDeleteProgram(program);
2354 TRACKING_CONTEXT(DeletedProgram(this, program));
2357 void fDeleteShader(GLuint shader) {
2358 raw_fDeleteShader(shader);
2359 TRACKING_CONTEXT(DeletedShader(this, shader));
2362 void fDeleteBuffers(GLsizei n, const GLuint* names) {
2363 raw_fDeleteBuffers(n, names);
2364 TRACKING_CONTEXT(DeletedBuffers(this, n, names));
2367 void fDeleteFramebuffers(GLsizei n, const GLuint* names);
2369 void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2370 raw_fDeleteRenderbuffers(n, names);
2371 TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
2374 void fDeleteTextures(GLsizei n, const GLuint* names) {
2375 #ifdef XP_MACOSX
2376 // On the Mac the call to fDeleteTextures() triggers a flush. But it
2377 // happens at the wrong time, which can lead to crashes. To work around
2378 // this we call fFlush() explicitly ourselves, before the call to
2379 // fDeleteTextures(). This fixes bug 1666293.
2380 fFlush();
2381 #endif
2382 raw_fDeleteTextures(n, names);
2383 TRACKING_CONTEXT(DeletedTextures(this, n, names));
2386 // -----------------------------------------------------------------------------
2387 // Extension ARB_sync (GL)
2388 public:
2389 GLsync fFenceSync(GLenum condition, GLbitfield flags) {
2390 GLsync ret = 0;
2391 BEFORE_GL_CALL;
2392 ASSERT_SYMBOL_PRESENT(fFenceSync);
2393 ret = mSymbols.fFenceSync(condition, flags);
2394 OnSyncCall();
2395 AFTER_GL_CALL;
2396 return ret;
2399 realGLboolean fIsSync(GLsync sync) {
2400 realGLboolean ret = false;
2401 BEFORE_GL_CALL;
2402 ASSERT_SYMBOL_PRESENT(fIsSync);
2403 ret = mSymbols.fIsSync(sync);
2404 OnSyncCall();
2405 AFTER_GL_CALL;
2406 return ret;
2409 void fDeleteSync(GLsync sync) {
2410 BEFORE_GL_CALL;
2411 ASSERT_SYMBOL_PRESENT(fDeleteSync);
2412 mSymbols.fDeleteSync(sync);
2413 AFTER_GL_CALL;
2416 GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2417 GLenum ret = 0;
2418 BEFORE_GL_CALL;
2419 ASSERT_SYMBOL_PRESENT(fClientWaitSync);
2420 ret = mSymbols.fClientWaitSync(sync, flags, timeout);
2421 OnSyncCall();
2422 AFTER_GL_CALL;
2423 return ret;
2426 void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2427 BEFORE_GL_CALL;
2428 ASSERT_SYMBOL_PRESENT(fWaitSync);
2429 mSymbols.fWaitSync(sync, flags, timeout);
2430 AFTER_GL_CALL;
2433 void fGetInteger64v(GLenum pname, GLint64* params) {
2434 BEFORE_GL_CALL;
2435 ASSERT_SYMBOL_PRESENT(fGetInteger64v);
2436 mSymbols.fGetInteger64v(pname, params);
2437 AFTER_GL_CALL;
2440 void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,
2441 GLint* values) {
2442 BEFORE_GL_CALL;
2443 ASSERT_SYMBOL_PRESENT(fGetSynciv);
2444 mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
2445 OnSyncCall();
2446 AFTER_GL_CALL;
2449 // -----------------------------------------------------------------------------
2450 // Extension OES_EGL_image (GLES)
2451 public:
2452 void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
2453 BEFORE_GL_CALL;
2454 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
2455 mSymbols.fEGLImageTargetTexture2D(target, image);
2456 AFTER_GL_CALL;
2457 mHeavyGLCallsSinceLastFlush = true;
2460 void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image) {
2461 BEFORE_GL_CALL;
2462 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
2463 mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
2464 AFTER_GL_CALL;
2467 // -----------------------------------------------------------------------------
2468 // Package XXX_bind_buffer_offset
2469 public:
2470 void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer,
2471 GLintptr offset) {
2472 BEFORE_GL_CALL;
2473 ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
2474 mSymbols.fBindBufferOffset(target, index, buffer, offset);
2475 AFTER_GL_CALL;
2478 // -----------------------------------------------------------------------------
2479 // Package XXX_draw_buffers
2480 public:
2481 void fDrawBuffers(GLsizei n, const GLenum* bufs) {
2482 BEFORE_GL_CALL;
2483 ASSERT_SYMBOL_PRESENT(fDrawBuffers);
2484 mSymbols.fDrawBuffers(n, bufs);
2485 AFTER_GL_CALL;
2488 // -----------------------------------------------------------------------------
2489 // Package XXX_draw_instanced
2490 public:
2491 void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2492 GLsizei primcount) {
2493 BeforeGLDrawCall();
2494 raw_fDrawArraysInstanced(mode, first, count, primcount);
2495 AfterGLDrawCall();
2498 void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
2499 const GLvoid* indices, GLsizei primcount) {
2500 BeforeGLDrawCall();
2501 raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
2502 AfterGLDrawCall();
2505 private:
2506 void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
2507 GLsizei primcount) {
2508 BEFORE_GL_CALL;
2509 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
2510 mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
2511 AFTER_GL_CALL;
2514 void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
2515 const GLvoid* indices, GLsizei primcount) {
2516 BEFORE_GL_CALL;
2517 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
2518 mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
2519 AFTER_GL_CALL;
2522 // -----------------------------------------------------------------------------
2523 // Package XXX_framebuffer_blit
2524 public:
2525 // Draw/Read
2526 void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2527 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2528 GLbitfield mask, GLenum filter) {
2529 BeforeGLDrawCall();
2530 BeforeGLReadCall();
2531 raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
2532 mask, filter);
2533 AfterGLReadCall();
2534 AfterGLDrawCall();
2537 private:
2538 void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2539 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2540 GLbitfield mask, GLenum filter) {
2541 BEFORE_GL_CALL;
2542 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
2543 mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
2544 dstY1, mask, filter);
2545 AFTER_GL_CALL;
2548 // -----------------------------------------------------------------------------
2549 // Package XXX_framebuffer_multisample
2550 public:
2551 void fRenderbufferStorageMultisample(GLenum target, GLsizei samples,
2552 GLenum internalFormat, GLsizei width,
2553 GLsizei height) {
2554 BEFORE_GL_CALL;
2555 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
2556 mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat,
2557 width, height);
2558 AFTER_GL_CALL;
2561 // -----------------------------------------------------------------------------
2562 // GL 3.0, GL ES 3.0 & EXT_gpu_shader4
2563 public:
2564 void fGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) {
2565 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv);
2566 BEFORE_GL_CALL;
2567 mSymbols.fGetVertexAttribIiv(index, pname, params);
2568 OnSyncCall();
2569 AFTER_GL_CALL;
2572 void fGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) {
2573 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv);
2574 BEFORE_GL_CALL;
2575 mSymbols.fGetVertexAttribIuiv(index, pname, params);
2576 OnSyncCall();
2577 AFTER_GL_CALL;
2580 void fVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) {
2581 BEFORE_GL_CALL;
2582 ASSERT_SYMBOL_PRESENT(fVertexAttribI4i);
2583 mSymbols.fVertexAttribI4i(index, x, y, z, w);
2584 AFTER_GL_CALL;
2587 void fVertexAttribI4iv(GLuint index, const GLint* v) {
2588 BEFORE_GL_CALL;
2589 ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv);
2590 mSymbols.fVertexAttribI4iv(index, v);
2591 AFTER_GL_CALL;
2594 void fVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) {
2595 BEFORE_GL_CALL;
2596 ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui);
2597 mSymbols.fVertexAttribI4ui(index, x, y, z, w);
2598 AFTER_GL_CALL;
2601 void fVertexAttribI4uiv(GLuint index, const GLuint* v) {
2602 BEFORE_GL_CALL;
2603 ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv);
2604 mSymbols.fVertexAttribI4uiv(index, v);
2605 AFTER_GL_CALL;
2608 void fVertexAttribIPointer(GLuint index, GLint size, GLenum type,
2609 GLsizei stride, const GLvoid* offset) {
2610 BEFORE_GL_CALL;
2611 ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer);
2612 mSymbols.fVertexAttribIPointer(index, size, type, stride, offset);
2613 AFTER_GL_CALL;
2616 void fUniform1ui(GLint location, GLuint v0) {
2617 BEFORE_GL_CALL;
2618 ASSERT_SYMBOL_PRESENT(fUniform1ui);
2619 mSymbols.fUniform1ui(location, v0);
2620 AFTER_GL_CALL;
2623 void fUniform2ui(GLint location, GLuint v0, GLuint v1) {
2624 BEFORE_GL_CALL;
2625 ASSERT_SYMBOL_PRESENT(fUniform2ui);
2626 mSymbols.fUniform2ui(location, v0, v1);
2627 AFTER_GL_CALL;
2630 void fUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {
2631 BEFORE_GL_CALL;
2632 ASSERT_SYMBOL_PRESENT(fUniform3ui);
2633 mSymbols.fUniform3ui(location, v0, v1, v2);
2634 AFTER_GL_CALL;
2637 void fUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
2638 BEFORE_GL_CALL;
2639 ASSERT_SYMBOL_PRESENT(fUniform4ui);
2640 mSymbols.fUniform4ui(location, v0, v1, v2, v3);
2641 AFTER_GL_CALL;
2644 void fUniform1uiv(GLint location, GLsizei count, const GLuint* value) {
2645 BEFORE_GL_CALL;
2646 ASSERT_SYMBOL_PRESENT(fUniform1uiv);
2647 mSymbols.fUniform1uiv(location, count, value);
2648 AFTER_GL_CALL;
2651 void fUniform2uiv(GLint location, GLsizei count, const GLuint* value) {
2652 BEFORE_GL_CALL;
2653 ASSERT_SYMBOL_PRESENT(fUniform2uiv);
2654 mSymbols.fUniform2uiv(location, count, value);
2655 AFTER_GL_CALL;
2658 void fUniform3uiv(GLint location, GLsizei count, const GLuint* value) {
2659 BEFORE_GL_CALL;
2660 ASSERT_SYMBOL_PRESENT(fUniform3uiv);
2661 mSymbols.fUniform3uiv(location, count, value);
2662 AFTER_GL_CALL;
2665 void fUniform4uiv(GLint location, GLsizei count, const GLuint* value) {
2666 BEFORE_GL_CALL;
2667 ASSERT_SYMBOL_PRESENT(fUniform4uiv);
2668 mSymbols.fUniform4uiv(location, count, value);
2669 AFTER_GL_CALL;
2672 GLint fGetFragDataLocation(GLuint program, const GLchar* name) {
2673 GLint result = 0;
2674 BEFORE_GL_CALL;
2675 ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
2676 result = mSymbols.fGetFragDataLocation(program, name);
2677 OnSyncCall();
2678 AFTER_GL_CALL;
2679 return result;
2682 // -----------------------------------------------------------------------------
2683 // Package XXX_instanced_arrays
2684 public:
2685 void fVertexAttribDivisor(GLuint index, GLuint divisor) {
2686 BEFORE_GL_CALL;
2687 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
2688 mSymbols.fVertexAttribDivisor(index, divisor);
2689 AFTER_GL_CALL;
2692 // -----------------------------------------------------------------------------
2693 // Feature internalformat_query
2694 public:
2695 void fGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
2696 GLsizei bufSize, GLint* params) {
2697 BEFORE_GL_CALL;
2698 ASSERT_SYMBOL_PRESENT(fGetInternalformativ);
2699 mSymbols.fGetInternalformativ(target, internalformat, pname, bufSize,
2700 params);
2701 OnSyncCall();
2702 AFTER_GL_CALL;
2705 // -----------------------------------------------------------------------------
2706 // Package XXX_query_counter
2708 * XXX_query_counter:
2709 * - depends on XXX_query_objects
2710 * - provide all followed entry points
2711 * - provide GL_TIMESTAMP
2713 public:
2714 void fQueryCounter(GLuint id, GLenum target) {
2715 BEFORE_GL_CALL;
2716 ASSERT_SYMBOL_PRESENT(fQueryCounter);
2717 mSymbols.fQueryCounter(id, target);
2718 AFTER_GL_CALL;
2721 // -----------------------------------------------------------------------------
2722 // Package XXX_query_objects
2724 * XXX_query_objects:
2725 * - provide all followed entry points
2727 * XXX_occlusion_query2:
2728 * - depends on XXX_query_objects
2729 * - provide ANY_SAMPLES_PASSED
2731 * XXX_occlusion_query_boolean:
2732 * - depends on XXX_occlusion_query2
2733 * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2735 public:
2736 void fDeleteQueries(GLsizei n, const GLuint* names) {
2737 BEFORE_GL_CALL;
2738 ASSERT_SYMBOL_PRESENT(fDeleteQueries);
2739 mSymbols.fDeleteQueries(n, names);
2740 AFTER_GL_CALL;
2741 TRACKING_CONTEXT(DeletedQueries(this, n, names));
2744 void fGenQueries(GLsizei n, GLuint* names) {
2745 BEFORE_GL_CALL;
2746 ASSERT_SYMBOL_PRESENT(fGenQueries);
2747 mSymbols.fGenQueries(n, names);
2748 AFTER_GL_CALL;
2749 TRACKING_CONTEXT(CreatedQueries(this, n, names));
2752 void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
2753 BEFORE_GL_CALL;
2754 ASSERT_SYMBOL_PRESENT(fGetQueryiv);
2755 mSymbols.fGetQueryiv(target, pname, params);
2756 OnSyncCall();
2757 AFTER_GL_CALL;
2760 void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
2761 BEFORE_GL_CALL;
2762 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
2763 mSymbols.fGetQueryObjectuiv(id, pname, params);
2764 OnSyncCall();
2765 AFTER_GL_CALL;
2768 realGLboolean fIsQuery(GLuint query) {
2769 realGLboolean retval = false;
2770 BEFORE_GL_CALL;
2771 ASSERT_SYMBOL_PRESENT(fIsQuery);
2772 retval = mSymbols.fIsQuery(query);
2773 OnSyncCall();
2774 AFTER_GL_CALL;
2775 return retval;
2778 // -----------------------------------------------------------------------------
2779 // Package XXX_get_query_object_i64v
2781 * XXX_get_query_object_i64v:
2782 * - depends on XXX_query_objects
2783 * - provide the followed entry point
2785 public:
2786 void fGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params) {
2787 BEFORE_GL_CALL;
2788 ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v);
2789 mSymbols.fGetQueryObjecti64v(id, pname, params);
2790 OnSyncCall();
2791 AFTER_GL_CALL;
2794 void fGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
2795 BEFORE_GL_CALL;
2796 ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v);
2797 mSymbols.fGetQueryObjectui64v(id, pname, params);
2798 OnSyncCall();
2799 AFTER_GL_CALL;
2802 // -----------------------------------------------------------------------------
2803 // Package XXX_get_query_object_iv
2805 * XXX_get_query_object_iv:
2806 * - depends on XXX_query_objects
2807 * - provide the followed entry point
2809 * XXX_occlusion_query:
2810 * - depends on XXX_get_query_object_iv
2811 * - provide LOCAL_GL_SAMPLES_PASSED
2813 public:
2814 void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
2815 BEFORE_GL_CALL;
2816 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
2817 mSymbols.fGetQueryObjectiv(id, pname, params);
2818 OnSyncCall();
2819 AFTER_GL_CALL;
2822 // -----------------------------------------------------------------------------
2823 // GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
2824 public:
2825 void fBindBufferBase(GLenum target, GLuint index, GLuint buffer) {
2826 BEFORE_GL_CALL;
2827 ASSERT_SYMBOL_PRESENT(fBindBufferBase);
2828 mSymbols.fBindBufferBase(target, index, buffer);
2829 AFTER_GL_CALL;
2832 void fBindBufferRange(GLenum target, GLuint index, GLuint buffer,
2833 GLintptr offset, GLsizeiptr size) {
2834 BEFORE_GL_CALL;
2835 ASSERT_SYMBOL_PRESENT(fBindBufferRange);
2836 mSymbols.fBindBufferRange(target, index, buffer, offset, size);
2837 AFTER_GL_CALL;
2840 void fGenTransformFeedbacks(GLsizei n, GLuint* ids) {
2841 BEFORE_GL_CALL;
2842 ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks);
2843 mSymbols.fGenTransformFeedbacks(n, ids);
2844 OnSyncCall();
2845 AFTER_GL_CALL;
2848 void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) {
2849 BEFORE_GL_CALL;
2850 ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
2851 mSymbols.fDeleteTransformFeedbacks(n, ids);
2852 AFTER_GL_CALL;
2855 realGLboolean fIsTransformFeedback(GLuint id) {
2856 realGLboolean result = false;
2857 BEFORE_GL_CALL;
2858 ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
2859 result = mSymbols.fIsTransformFeedback(id);
2860 OnSyncCall();
2861 AFTER_GL_CALL;
2862 return result;
2865 void fBindTransformFeedback(GLenum target, GLuint id) {
2866 BEFORE_GL_CALL;
2867 ASSERT_SYMBOL_PRESENT(fBindTransformFeedback);
2868 mSymbols.fBindTransformFeedback(target, id);
2869 AFTER_GL_CALL;
2872 void fBeginTransformFeedback(GLenum primitiveMode) {
2873 BEFORE_GL_CALL;
2874 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
2875 mSymbols.fBeginTransformFeedback(primitiveMode);
2876 AFTER_GL_CALL;
2879 void fEndTransformFeedback() {
2880 BEFORE_GL_CALL;
2881 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
2882 mSymbols.fEndTransformFeedback();
2883 AFTER_GL_CALL;
2886 void fTransformFeedbackVaryings(GLuint program, GLsizei count,
2887 const GLchar* const* varyings,
2888 GLenum bufferMode) {
2889 BEFORE_GL_CALL;
2890 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
2891 mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
2892 AFTER_GL_CALL;
2895 void fGetTransformFeedbackVarying(GLuint program, GLuint index,
2896 GLsizei bufSize, GLsizei* length,
2897 GLsizei* size, GLenum* type, GLchar* name) {
2898 BEFORE_GL_CALL;
2899 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
2900 mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size,
2901 type, name);
2902 OnSyncCall();
2903 AFTER_GL_CALL;
2906 void fPauseTransformFeedback() {
2907 BEFORE_GL_CALL;
2908 ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback);
2909 mSymbols.fPauseTransformFeedback();
2910 AFTER_GL_CALL;
2913 void fResumeTransformFeedback() {
2914 BEFORE_GL_CALL;
2915 ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback);
2916 mSymbols.fResumeTransformFeedback();
2917 AFTER_GL_CALL;
2920 void fGetIntegeri_v(GLenum param, GLuint index, GLint* values) {
2921 BEFORE_GL_CALL;
2922 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
2923 mSymbols.fGetIntegeri_v(param, index, values);
2924 OnSyncCall();
2925 AFTER_GL_CALL;
2928 void fGetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
2929 ASSERT_SYMBOL_PRESENT(fGetInteger64i_v);
2930 BEFORE_GL_CALL;
2931 mSymbols.fGetInteger64i_v(target, index, data);
2932 OnSyncCall();
2933 AFTER_GL_CALL;
2936 // -----------------------------------------------------------------------------
2937 // Package XXX_vertex_array_object
2938 public:
2939 void fBindVertexArray(GLuint array) {
2940 BEFORE_GL_CALL;
2941 ASSERT_SYMBOL_PRESENT(fBindVertexArray);
2942 mSymbols.fBindVertexArray(array);
2943 AFTER_GL_CALL;
2946 void fDeleteVertexArrays(GLsizei n, const GLuint* arrays) {
2947 BEFORE_GL_CALL;
2948 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
2949 mSymbols.fDeleteVertexArrays(n, arrays);
2950 AFTER_GL_CALL;
2953 void fGenVertexArrays(GLsizei n, GLuint* arrays) {
2954 BEFORE_GL_CALL;
2955 ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
2956 mSymbols.fGenVertexArrays(n, arrays);
2957 AFTER_GL_CALL;
2960 realGLboolean fIsVertexArray(GLuint array) {
2961 realGLboolean ret = false;
2962 BEFORE_GL_CALL;
2963 ASSERT_SYMBOL_PRESENT(fIsVertexArray);
2964 ret = mSymbols.fIsVertexArray(array);
2965 OnSyncCall();
2966 AFTER_GL_CALL;
2967 return ret;
2970 // -----------------------------------------------------------------------------
2971 // Extension NV_fence
2972 public:
2973 void fGenFences(GLsizei n, GLuint* fences) {
2974 ASSERT_SYMBOL_PRESENT(fGenFences);
2975 BEFORE_GL_CALL;
2976 mSymbols.fGenFences(n, fences);
2977 AFTER_GL_CALL;
2980 void fDeleteFences(GLsizei n, const GLuint* fences) {
2981 ASSERT_SYMBOL_PRESENT(fDeleteFences);
2982 BEFORE_GL_CALL;
2983 mSymbols.fDeleteFences(n, fences);
2984 AFTER_GL_CALL;
2987 void fSetFence(GLuint fence, GLenum condition) {
2988 ASSERT_SYMBOL_PRESENT(fSetFence);
2989 BEFORE_GL_CALL;
2990 mSymbols.fSetFence(fence, condition);
2991 AFTER_GL_CALL;
2994 realGLboolean fTestFence(GLuint fence) {
2995 realGLboolean ret = false;
2996 ASSERT_SYMBOL_PRESENT(fTestFence);
2997 BEFORE_GL_CALL;
2998 ret = mSymbols.fTestFence(fence);
2999 OnSyncCall();
3000 AFTER_GL_CALL;
3001 return ret;
3004 void fFinishFence(GLuint fence) {
3005 ASSERT_SYMBOL_PRESENT(fFinishFence);
3006 BEFORE_GL_CALL;
3007 mSymbols.fFinishFence(fence);
3008 OnSyncCall();
3009 AFTER_GL_CALL;
3012 realGLboolean fIsFence(GLuint fence) {
3013 realGLboolean ret = false;
3014 ASSERT_SYMBOL_PRESENT(fIsFence);
3015 BEFORE_GL_CALL;
3016 ret = mSymbols.fIsFence(fence);
3017 OnSyncCall();
3018 AFTER_GL_CALL;
3019 return ret;
3022 void fGetFenceiv(GLuint fence, GLenum pname, GLint* params) {
3023 ASSERT_SYMBOL_PRESENT(fGetFenceiv);
3024 BEFORE_GL_CALL;
3025 mSymbols.fGetFenceiv(fence, pname, params);
3026 OnSyncCall();
3027 AFTER_GL_CALL;
3030 // -----------------------------------------------------------------------------
3031 // Extension NV_texture_barrier
3032 public:
3033 void fTextureBarrier() {
3034 ASSERT_SYMBOL_PRESENT(fTextureBarrier);
3035 BEFORE_GL_CALL;
3036 mSymbols.fTextureBarrier();
3037 AFTER_GL_CALL;
3040 // Core GL & Extension ARB_copy_buffer
3041 public:
3042 void fCopyBufferSubData(GLenum readtarget, GLenum writetarget,
3043 GLintptr readoffset, GLintptr writeoffset,
3044 GLsizeiptr size) {
3045 BEFORE_GL_CALL;
3046 ASSERT_SYMBOL_PRESENT(fCopyBufferSubData);
3047 mSymbols.fCopyBufferSubData(readtarget, writetarget, readoffset,
3048 writeoffset, size);
3049 AFTER_GL_CALL;
3052 // -----------------------------------------------------------------------------
3053 // Core GL & Extension ARB_map_buffer_range
3054 public:
3055 void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
3056 GLbitfield access) {
3057 void* data = nullptr;
3058 ASSERT_SYMBOL_PRESENT(fMapBufferRange);
3059 BEFORE_GL_CALL;
3060 data = mSymbols.fMapBufferRange(target, offset, length, access);
3061 OnSyncCall();
3062 AFTER_GL_CALL;
3063 return data;
3066 void fFlushMappedBufferRange(GLenum target, GLintptr offset,
3067 GLsizeiptr length) {
3068 ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
3069 BEFORE_GL_CALL;
3070 mSymbols.fFlushMappedBufferRange(target, offset, length);
3071 AFTER_GL_CALL;
3074 // -----------------------------------------------------------------------------
3075 // Core GL & Extension ARB_sampler_objects
3076 public:
3077 void fGenSamplers(GLsizei count, GLuint* samplers) {
3078 BEFORE_GL_CALL;
3079 ASSERT_SYMBOL_PRESENT(fGenSamplers);
3080 mSymbols.fGenSamplers(count, samplers);
3081 AFTER_GL_CALL;
3084 void fDeleteSamplers(GLsizei count, const GLuint* samplers) {
3085 BEFORE_GL_CALL;
3086 ASSERT_SYMBOL_PRESENT(fDeleteSamplers);
3087 mSymbols.fDeleteSamplers(count, samplers);
3088 AFTER_GL_CALL;
3091 realGLboolean fIsSampler(GLuint sampler) {
3092 realGLboolean result = false;
3093 BEFORE_GL_CALL;
3094 ASSERT_SYMBOL_PRESENT(fIsSampler);
3095 result = mSymbols.fIsSampler(sampler);
3096 OnSyncCall();
3097 AFTER_GL_CALL;
3098 return result;
3101 void fBindSampler(GLuint unit, GLuint sampler) {
3102 BEFORE_GL_CALL;
3103 ASSERT_SYMBOL_PRESENT(fBindSampler);
3104 mSymbols.fBindSampler(unit, sampler);
3105 AFTER_GL_CALL;
3108 void fSamplerParameteri(GLuint sampler, GLenum pname, GLint param) {
3109 BEFORE_GL_CALL;
3110 ASSERT_SYMBOL_PRESENT(fSamplerParameteri);
3111 mSymbols.fSamplerParameteri(sampler, pname, param);
3112 AFTER_GL_CALL;
3115 void fSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) {
3116 BEFORE_GL_CALL;
3117 ASSERT_SYMBOL_PRESENT(fSamplerParameteriv);
3118 mSymbols.fSamplerParameteriv(sampler, pname, param);
3119 AFTER_GL_CALL;
3122 void fSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) {
3123 BEFORE_GL_CALL;
3124 ASSERT_SYMBOL_PRESENT(fSamplerParameterf);
3125 mSymbols.fSamplerParameterf(sampler, pname, param);
3126 AFTER_GL_CALL;
3129 void fSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) {
3130 BEFORE_GL_CALL;
3131 ASSERT_SYMBOL_PRESENT(fSamplerParameterfv);
3132 mSymbols.fSamplerParameterfv(sampler, pname, param);
3133 AFTER_GL_CALL;
3136 void fGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) {
3137 BEFORE_GL_CALL;
3138 ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv);
3139 mSymbols.fGetSamplerParameteriv(sampler, pname, params);
3140 AFTER_GL_CALL;
3143 void fGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) {
3144 BEFORE_GL_CALL;
3145 ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv);
3146 mSymbols.fGetSamplerParameterfv(sampler, pname, params);
3147 AFTER_GL_CALL;
3150 // -----------------------------------------------------------------------------
3151 // Core GL & Extension ARB_uniform_buffer_object
3152 public:
3153 void fGetUniformIndices(GLuint program, GLsizei uniformCount,
3154 const GLchar* const* uniformNames,
3155 GLuint* uniformIndices) {
3156 ASSERT_SYMBOL_PRESENT(fGetUniformIndices);
3157 BEFORE_GL_CALL;
3158 mSymbols.fGetUniformIndices(program, uniformCount, uniformNames,
3159 uniformIndices);
3160 OnSyncCall();
3161 AFTER_GL_CALL;
3164 void fGetActiveUniformsiv(GLuint program, GLsizei uniformCount,
3165 const GLuint* uniformIndices, GLenum pname,
3166 GLint* params) {
3167 ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
3168 BEFORE_GL_CALL;
3169 mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname,
3170 params);
3171 OnSyncCall();
3172 AFTER_GL_CALL;
3175 GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
3176 GLuint result = 0;
3177 ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
3178 BEFORE_GL_CALL;
3179 result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
3180 OnSyncCall();
3181 AFTER_GL_CALL;
3182 return result;
3185 void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
3186 GLenum pname, GLint* params) {
3187 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv);
3188 BEFORE_GL_CALL;
3189 mSymbols.fGetActiveUniformBlockiv(program, uniformBlockIndex, pname,
3190 params);
3191 OnSyncCall();
3192 AFTER_GL_CALL;
3195 void fGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex,
3196 GLsizei bufSize, GLsizei* length,
3197 GLchar* uniformBlockName) {
3198 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName);
3199 BEFORE_GL_CALL;
3200 mSymbols.fGetActiveUniformBlockName(program, uniformBlockIndex, bufSize,
3201 length, uniformBlockName);
3202 OnSyncCall();
3203 AFTER_GL_CALL;
3206 void fUniformBlockBinding(GLuint program, GLuint uniformBlockIndex,
3207 GLuint uniformBlockBinding) {
3208 ASSERT_SYMBOL_PRESENT(fUniformBlockBinding);
3209 BEFORE_GL_CALL;
3210 mSymbols.fUniformBlockBinding(program, uniformBlockIndex,
3211 uniformBlockBinding);
3212 AFTER_GL_CALL;
3215 // -----------------------------------------------------------------------------
3216 // Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
3217 void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
3218 GLsizei width, GLsizei height) {
3219 BEFORE_GL_CALL;
3220 ASSERT_SYMBOL_PRESENT(fTexStorage2D);
3221 mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
3222 OnSyncCall();
3223 AFTER_GL_CALL;
3226 void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
3227 GLsizei width, GLsizei height, GLsizei depth) {
3228 BEFORE_GL_CALL;
3229 ASSERT_SYMBOL_PRESENT(fTexStorage3D);
3230 mSymbols.fTexStorage3D(target, levels, internalformat, width, height,
3231 depth);
3232 OnSyncCall();
3233 AFTER_GL_CALL;
3236 // -----------------------------------------------------------------------------
3237 // 3D Textures
3238 void fTexImage3D(GLenum target, GLint level, GLint internalFormat,
3239 GLsizei width, GLsizei height, GLsizei depth, GLint border,
3240 GLenum format, GLenum type, const GLvoid* data) {
3241 BEFORE_GL_CALL;
3242 ASSERT_SYMBOL_PRESENT(fTexImage3D);
3243 mSymbols.fTexImage3D(target, level, internalFormat, width, height, depth,
3244 border, format, type, data);
3245 OnSyncCall();
3246 AFTER_GL_CALL;
3249 void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
3250 GLint zoffset, GLsizei width, GLsizei height,
3251 GLsizei depth, GLenum format, GLenum type,
3252 const GLvoid* pixels) {
3253 BEFORE_GL_CALL;
3254 ASSERT_SYMBOL_PRESENT(fTexSubImage3D);
3255 mSymbols.fTexSubImage3D(target, level, xoffset, yoffset, zoffset, width,
3256 height, depth, format, type, pixels);
3257 OnSyncCall();
3258 AFTER_GL_CALL;
3261 void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
3262 GLint yoffset, GLint zoffset, GLint x, GLint y,
3263 GLsizei width, GLsizei height) {
3264 BeforeGLReadCall();
3265 BEFORE_GL_CALL;
3266 ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D);
3267 mSymbols.fCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y,
3268 width, height);
3269 AFTER_GL_CALL;
3270 AfterGLReadCall();
3273 void fCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
3274 GLsizei width, GLsizei height, GLsizei depth,
3275 GLint border, GLsizei imageSize,
3276 const GLvoid* data) {
3277 BEFORE_GL_CALL;
3278 ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D);
3279 mSymbols.fCompressedTexImage3D(target, level, internalformat, width, height,
3280 depth, border, imageSize, data);
3281 AFTER_GL_CALL;
3284 void fCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
3285 GLint yoffset, GLint zoffset, GLsizei width,
3286 GLsizei height, GLsizei depth, GLenum format,
3287 GLsizei imageSize, const GLvoid* data) {
3288 BEFORE_GL_CALL;
3289 ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D);
3290 mSymbols.fCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset,
3291 width, height, depth, format, imageSize,
3292 data);
3293 AFTER_GL_CALL;
3296 // -----------------------------------------------------------------------------
3297 // GL3+, ES3+
3299 const GLubyte* fGetStringi(GLenum name, GLuint index) {
3300 const GLubyte* ret = nullptr;
3301 BEFORE_GL_CALL;
3302 ASSERT_SYMBOL_PRESENT(fGetStringi);
3303 ret = mSymbols.fGetStringi(name, index);
3304 OnSyncCall();
3305 AFTER_GL_CALL;
3306 return ret;
3309 // -----------------------------------------------------------------------------
3310 // APPLE_framebuffer_multisample
3312 void fResolveMultisampleFramebufferAPPLE() {
3313 BEFORE_GL_CALL;
3314 ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE);
3315 mSymbols.fResolveMultisampleFramebufferAPPLE();
3316 AFTER_GL_CALL;
3319 // -----------------------------------------------------------------------------
3320 // APPLE_fence
3322 void fFinishObjectAPPLE(GLenum object, GLint name) {
3323 BEFORE_GL_CALL;
3324 ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE);
3325 mSymbols.fFinishObjectAPPLE(object, name);
3326 AFTER_GL_CALL;
3329 realGLboolean fTestObjectAPPLE(GLenum object, GLint name) {
3330 realGLboolean ret = false;
3331 BEFORE_GL_CALL;
3332 ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE);
3333 ret = mSymbols.fTestObjectAPPLE(object, name);
3334 AFTER_GL_CALL;
3335 return ret;
3338 // -----------------------------------------------------------------------------
3339 // prim_restart
3341 void fPrimitiveRestartIndex(GLuint index) {
3342 BEFORE_GL_CALL;
3343 ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex);
3344 mSymbols.fPrimitiveRestartIndex(index);
3345 AFTER_GL_CALL;
3348 // -----------------------------------------------------------------------------
3349 // multiview
3351 void fFramebufferTextureMultiview(GLenum target, GLenum attachment,
3352 GLuint texture, GLint level,
3353 GLint baseViewIndex,
3354 GLsizei numViews) const {
3355 BEFORE_GL_CALL;
3356 ASSERT_SYMBOL_PRESENT(fFramebufferTextureMultiview);
3357 mSymbols.fFramebufferTextureMultiview(target, attachment, texture, level,
3358 baseViewIndex, numViews);
3359 AFTER_GL_CALL;
3362 // -
3363 // draw_buffers_indexed
3365 void fBlendEquationSeparatei(GLuint i, GLenum modeRGB,
3366 GLenum modeAlpha) const {
3367 BEFORE_GL_CALL;
3368 mSymbols.fBlendEquationSeparatei(i, modeRGB, modeAlpha);
3369 AFTER_GL_CALL;
3372 void fBlendFuncSeparatei(GLuint i, GLenum sfactorRGB, GLenum dfactorRGB,
3373 GLenum sfactorAlpha, GLenum dfactorAlpha) const {
3374 BEFORE_GL_CALL;
3375 mSymbols.fBlendFuncSeparatei(i, sfactorRGB, dfactorRGB, sfactorAlpha,
3376 dfactorAlpha);
3377 AFTER_GL_CALL;
3380 void fColorMaski(GLuint i, realGLboolean red, realGLboolean green,
3381 realGLboolean blue, realGLboolean alpha) const {
3382 BEFORE_GL_CALL;
3383 mSymbols.fColorMaski(i, red, green, blue, alpha);
3384 AFTER_GL_CALL;
3387 void fDisablei(GLenum capability, GLuint i) const {
3388 BEFORE_GL_CALL;
3389 mSymbols.fDisablei(capability, i);
3390 AFTER_GL_CALL;
3393 void fEnablei(GLenum capability, GLuint i) const {
3394 BEFORE_GL_CALL;
3395 mSymbols.fEnablei(capability, i);
3396 AFTER_GL_CALL;
3399 // -
3401 void fProvokingVertex(GLenum mode) const {
3402 BEFORE_GL_CALL;
3403 mSymbols.fProvokingVertex(mode);
3404 AFTER_GL_CALL;
3407 // -
3409 #undef BEFORE_GL_CALL
3410 #undef AFTER_GL_CALL
3411 #undef ASSERT_SYMBOL_PRESENT
3412 // #undef TRACKING_CONTEXT // Needed in GLContext.cpp
3413 #undef ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL
3415 // -----------------------------------------------------------------------------
3416 // Constructor
3417 protected:
3418 explicit GLContext(const GLContextDesc&, GLContext* sharedContext = nullptr,
3419 bool canUseTLSIsCurrent = false);
3421 // -----------------------------------------------------------------------------
3422 // Destructor
3423 public:
3424 virtual ~GLContext();
3426 // Mark this context as destroyed. This will nullptr out all
3427 // the GL function pointers!
3428 void MarkDestroyed();
3430 protected:
3431 virtual void OnMarkDestroyed() {}
3433 // -----------------------------------------------------------------------------
3434 // Everything that isn't standard GL APIs
3435 protected:
3436 typedef gfx::SurfaceFormat SurfaceFormat;
3438 public:
3439 virtual void ReleaseSurface() {}
3441 bool IsDestroyed() const {
3442 // MarkDestroyed will mark all these as null.
3443 return mContextLost && mSymbols.fUseProgram == nullptr;
3446 GLContext* GetSharedContext() { return mSharedContext; }
3449 * Returns true if the thread on which this context was created is the
3450 * currently executing thread.
3452 bool IsValidOwningThread() const;
3454 static void PlatformStartup();
3456 public:
3458 * If this context wraps a double-buffered target, swap the back
3459 * and front buffers. It should be assumed that after a swap, the
3460 * contents of the new back buffer are undefined.
3462 virtual bool SwapBuffers() { return false; }
3465 * Stores a damage region (in origin bottom left coordinates), which
3466 * makes the next SwapBuffers call do eglSwapBuffersWithDamage if supported.
3468 * Note that even if only part of the context is damaged, the entire buffer
3469 * needs to be filled with up-to-date contents. This region is only a hint
3470 * telling the system compositor which parts of the buffer were updated.
3472 virtual void SetDamage(const nsIntRegion& aDamageRegion) {}
3475 * Get the buffer age. If it returns 0, that indicates the buffer state is
3476 * unknown and the entire frame should be redrawn.
3478 virtual GLint GetBufferAge() const { return 0; }
3481 * Defines a two-dimensional texture image for context target surface
3483 virtual bool BindTexImage() { return false; }
3485 * Releases a color buffer that is being used as a texture
3487 virtual bool ReleaseTexImage() { return false; }
3489 virtual Maybe<SymbolLoader> GetSymbolLoader() const = 0;
3491 void BindFB(GLuint fb) {
3492 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
3493 MOZ_GL_ASSERT(this, !fb || fIsFramebuffer(fb));
3496 void BindDrawFB(GLuint fb) {
3497 fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
3500 void BindReadFB(GLuint fb) {
3501 fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
3504 GLuint GetDrawFB() const {
3505 return GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT);
3508 GLuint GetReadFB() const {
3509 auto bindEnum = LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT;
3510 if (!IsSupported(GLFeature::split_framebuffer)) {
3511 bindEnum = LOCAL_GL_FRAMEBUFFER_BINDING;
3513 return GetIntAs<GLuint>(bindEnum);
3516 GLuint GetFB() const {
3517 const auto ret = GetDrawFB();
3518 MOZ_ASSERT(ret == GetReadFB());
3519 return ret;
3522 private:
3523 void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype,
3524 GLint* range, GLint* precision) {
3525 switch (precisiontype) {
3526 case LOCAL_GL_LOW_FLOAT:
3527 case LOCAL_GL_MEDIUM_FLOAT:
3528 case LOCAL_GL_HIGH_FLOAT:
3529 // Assume IEEE 754 precision
3530 range[0] = 127;
3531 range[1] = 127;
3532 *precision = 23;
3533 break;
3534 case LOCAL_GL_LOW_INT:
3535 case LOCAL_GL_MEDIUM_INT:
3536 case LOCAL_GL_HIGH_INT:
3537 // Some (most) hardware only supports single-precision floating-point
3538 // numbers, which can accurately represent integers up to +/-16777216
3539 range[0] = 24;
3540 range[1] = 24;
3541 *precision = 0;
3542 break;
3546 public:
3547 virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
3549 virtual GLenum GetPreferredEGLImageTextureTarget() const {
3550 #ifdef MOZ_WIDGET_GTK
3551 return LOCAL_GL_TEXTURE_2D;
3552 #else
3553 return IsExtensionSupported(OES_EGL_image_external)
3554 ? LOCAL_GL_TEXTURE_EXTERNAL
3555 : LOCAL_GL_TEXTURE_2D;
3556 #endif
3559 virtual bool RenewSurface(widget::CompositorWidget* aWidget) { return false; }
3561 // Shared code for GL extensions and GLX extensions.
3562 static bool ListHasExtension(const GLubyte* extensions,
3563 const char* extension);
3565 public:
3566 enum {
3567 DebugFlagEnabled = 1 << 0,
3568 DebugFlagTrace = 1 << 1,
3569 DebugFlagAbortOnError = 1 << 2
3572 const uint8_t mDebugFlags;
3573 static uint8_t ChooseDebugFlags(CreateContextFlags createFlags);
3575 protected:
3576 RefPtr<GLContext> mSharedContext;
3578 public:
3579 // The thread id which this context was created.
3580 Maybe<PlatformThreadId> mOwningThreadId;
3582 protected:
3583 GLContextSymbols mSymbols = {};
3585 UniquePtr<GLBlitHelper> mBlitHelper;
3586 UniquePtr<GLReadTexImageHelper> mReadTexImageHelper;
3588 public:
3589 GLBlitHelper* BlitHelper();
3590 GLReadTexImageHelper* ReadTexImageHelper();
3592 // Assumes shares are created by all sharing with the same global context.
3593 bool SharesWith(const GLContext* other) const {
3594 MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
3595 MOZ_ASSERT(!other->mSharedContext ||
3596 !other->mSharedContext->mSharedContext);
3597 MOZ_ASSERT(!this->mSharedContext || !other->mSharedContext ||
3598 this->mSharedContext == other->mSharedContext);
3600 const GLContext* thisShared =
3601 this->mSharedContext ? this->mSharedContext : this;
3602 const GLContext* otherShared =
3603 other->mSharedContext ? other->mSharedContext : other;
3605 return thisShared == otherShared;
3608 bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
3610 // Does not check completeness.
3611 void AttachBuffersToFB(GLuint colorTex, GLuint colorRB, GLuint depthRB,
3612 GLuint stencilRB, GLuint fb,
3613 GLenum target = LOCAL_GL_TEXTURE_2D);
3615 // Passing null is fine if the value you'd get is 0.
3616 bool AssembleOffscreenFBs(const GLuint colorMSRB, const GLuint depthRB,
3617 const GLuint stencilRB, const GLuint texture,
3618 GLuint* drawFB, GLuint* readFB);
3620 protected:
3621 SharedSurface* mLockedSurface = nullptr;
3623 public:
3624 void LockSurface(SharedSurface* surf) { mLockedSurface = surf; }
3626 void UnlockSurface(SharedSurface* surf) {
3627 MOZ_ASSERT(mLockedSurface == surf);
3628 mLockedSurface = nullptr;
3631 SharedSurface* GetLockedSurface() const { return mLockedSurface; }
3633 bool IsOffscreen() const { return mDesc.isOffscreen; }
3635 bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
3637 bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
3639 virtual bool Init();
3641 private:
3642 bool InitImpl();
3643 void LoadMoreSymbols(const SymbolLoader& loader);
3644 bool LoadExtSymbols(const SymbolLoader& loader, const SymLoadStruct* list,
3645 GLExtensions ext);
3646 bool LoadFeatureSymbols(const SymbolLoader& loader, const SymLoadStruct* list,
3647 GLFeature feature);
3649 protected:
3650 void InitExtensions();
3652 GLint mViewportRect[4] = {};
3653 GLint mScissorRect[4] = {};
3655 uint32_t mMaxTexOrRbSize = 0;
3656 GLint mMaxTextureSize = 0;
3657 GLint mMaxCubeMapTextureSize = 0;
3658 GLint mMaxRenderbufferSize = 0;
3659 GLint mMaxViewportDims[2] = {};
3660 GLsizei mMaxSamples = 0;
3661 bool mNeedsTextureSizeChecks = false;
3662 bool mNeedsFlushBeforeDeleteFB = false;
3663 bool mTextureAllocCrashesOnMapFailure = false;
3664 const bool mWorkAroundDriverBugs;
3665 mutable uint64_t mSyncGLCallCount = 0;
3667 bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width,
3668 GLsizei height) const {
3669 if (mNeedsTextureSizeChecks) {
3670 // some drivers incorrectly handle some large texture sizes that are below
3671 // the max texture size that they report. So we check ourselves against
3672 // our own values (mMax[CubeMap]TextureSize). see bug 737182 for Mac Intel
3673 // 2D textures see bug 684882 for Mac Intel cube map textures see bug
3674 // 814716 for Mesa Nouveau
3675 GLsizei maxSize =
3676 target == LOCAL_GL_TEXTURE_CUBE_MAP ||
3677 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
3678 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3679 ? mMaxCubeMapTextureSize
3680 : mMaxTextureSize;
3681 return width <= maxSize && height <= maxSize;
3683 return true;
3686 public:
3687 auto MaxSamples() const { return uint32_t(mMaxSamples); }
3688 auto MaxTextureSize() const { return uint32_t(mMaxTextureSize); }
3689 auto MaxRenderbufferSize() const { return uint32_t(mMaxRenderbufferSize); }
3690 auto MaxTexOrRbSize() const { return mMaxTexOrRbSize; }
3692 #ifdef MOZ_GL_DEBUG_BUILD
3693 void CreatedProgram(GLContext* aOrigin, GLuint aName);
3694 void CreatedShader(GLContext* aOrigin, GLuint aName);
3695 void CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3696 void CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3697 void CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3698 void CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3699 void CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3700 void DeletedProgram(GLContext* aOrigin, GLuint aName);
3701 void DeletedShader(GLContext* aOrigin, GLuint aName);
3702 void DeletedBuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3703 void DeletedQueries(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3704 void DeletedTextures(GLContext* aOrigin, GLsizei aCount,
3705 const GLuint* aNames);
3706 void DeletedFramebuffers(GLContext* aOrigin, GLsizei aCount,
3707 const GLuint* aNames);
3708 void DeletedRenderbuffers(GLContext* aOrigin, GLsizei aCount,
3709 const GLuint* aNames);
3711 void SharedContextDestroyed(GLContext* aChild);
3712 void ReportOutstandingNames();
3714 struct NamedResource {
3715 NamedResource() : origin(nullptr), name(0), originDeleted(false) {}
3717 NamedResource(GLContext* aOrigin, GLuint aName)
3718 : origin(aOrigin), name(aName), originDeleted(false) {}
3720 GLContext* origin;
3721 GLuint name;
3722 bool originDeleted;
3724 // for sorting
3725 bool operator<(const NamedResource& aOther) const {
3726 if (intptr_t(origin) < intptr_t(aOther.origin)) return true;
3727 if (name < aOther.name) return true;
3728 return false;
3730 bool operator==(const NamedResource& aOther) const {
3731 return origin == aOther.origin && name == aOther.name &&
3732 originDeleted == aOther.originDeleted;
3736 nsTArray<NamedResource> mTrackedPrograms;
3737 nsTArray<NamedResource> mTrackedShaders;
3738 nsTArray<NamedResource> mTrackedTextures;
3739 nsTArray<NamedResource> mTrackedFramebuffers;
3740 nsTArray<NamedResource> mTrackedRenderbuffers;
3741 nsTArray<NamedResource> mTrackedBuffers;
3742 nsTArray<NamedResource> mTrackedQueries;
3743 #endif
3745 protected:
3746 bool mHeavyGLCallsSinceLastFlush = false;
3748 public:
3749 void FlushIfHeavyGLCallsSinceLastFlush();
3750 static bool ShouldSpew();
3751 static bool ShouldDumpExts();
3753 // --
3755 void TexParams_SetClampNoMips(GLenum target = LOCAL_GL_TEXTURE_2D) {
3756 fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
3757 fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
3758 fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
3759 fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
3762 // --
3764 GLuint CreateFramebuffer() {
3765 GLuint x = 0;
3766 fGenFramebuffers(1, &x);
3767 return x;
3769 GLuint CreateRenderbuffer() {
3770 GLuint x = 0;
3771 fGenRenderbuffers(1, &x);
3772 return x;
3774 GLuint CreateTexture() {
3775 GLuint x = 0;
3776 fGenTextures(1, &x);
3777 return x;
3780 void DeleteFramebuffer(const GLuint x) { fDeleteFramebuffers(1, &x); }
3781 void DeleteRenderbuffer(const GLuint x) { fDeleteRenderbuffers(1, &x); }
3782 void DeleteTexture(const GLuint x) { fDeleteTextures(1, &x); }
3785 bool DoesStringMatch(const char* aString, const char* aWantedString);
3787 void SplitByChar(const nsACString& str, const char delim,
3788 std::vector<nsCString>* const out);
3790 template <size_t N>
3791 bool MarkBitfieldByString(const nsACString& str,
3792 const char* const (&markStrList)[N],
3793 std::bitset<N>* const out_markList) {
3794 for (size_t i = 0; i < N; i++) {
3795 if (str.Equals(markStrList[i])) {
3796 (*out_markList)[i] = 1;
3797 return true;
3800 return false;
3803 template <size_t N>
3804 void MarkBitfieldByStrings(const std::vector<nsCString>& strList,
3805 bool dumpStrings,
3806 const char* const (&markStrList)[N],
3807 std::bitset<N>* const out_markList) {
3808 for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
3809 const nsACString& str = *itr;
3810 const bool wasMarked = MarkBitfieldByString(str, markStrList, out_markList);
3811 if (dumpStrings)
3812 printf_stderr(" %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
3816 // -
3818 class Renderbuffer final {
3819 public:
3820 const WeakPtr<GLContext> weakGl;
3821 const GLuint name;
3823 private:
3824 static GLuint Create(GLContext& gl) {
3825 GLuint ret = 0;
3826 gl.fGenRenderbuffers(1, &ret);
3827 return ret;
3830 public:
3831 explicit Renderbuffer(GLContext& gl) : weakGl(&gl), name(Create(gl)) {}
3833 ~Renderbuffer() {
3834 const RefPtr<GLContext> gl = weakGl.get();
3835 if (!gl || !gl->MakeCurrent()) return;
3836 gl->fDeleteRenderbuffers(1, &name);
3840 // -
3842 class Texture final {
3843 public:
3844 const WeakPtr<GLContext> weakGl;
3845 const GLuint name;
3847 private:
3848 static GLuint Create(GLContext& gl) {
3849 GLuint ret = 0;
3850 gl.fGenTextures(1, &ret);
3851 return ret;
3854 public:
3855 explicit Texture(GLContext& gl) : weakGl(&gl), name(Create(gl)) {}
3857 ~Texture() {
3858 const RefPtr<GLContext> gl = weakGl.get();
3859 if (!gl || !gl->MakeCurrent()) return;
3860 gl->fDeleteTextures(1, &name);
3865 * Helper function that creates a 2D texture aSize.width x aSize.height with
3866 * storage type specified by aFormats. Returns GL texture object id.
3868 * See mozilla::gl::CreateTexture.
3870 UniquePtr<Texture> CreateTexture(GLContext&, const gfx::IntSize& size);
3873 * Helper function that calculates the number of bytes required per
3874 * texel for a texture from its format and type.
3876 uint32_t GetBytesPerTexel(GLenum format, GLenum type);
3878 void MesaMemoryLeakWorkaround();
3880 } /* namespace gl */
3881 } /* namespace mozilla */
3883 #endif /* GLCONTEXT_H_ */