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/. */
24 // Define MOZ_GL_DEBUG_BUILD unconditionally to enable GL debugging in opt
27 # define MOZ_GL_DEBUG_BUILD 1
30 #include "mozilla/IntegerRange.h"
31 #include "mozilla/RefPtr.h"
32 #include "mozilla/UniquePtr.h"
33 #include "mozilla/ThreadLocal.h"
35 #include "MozFramebuffer.h"
40 #include "nsRegionFwd.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"
57 class GLReadTexImageHelper
;
64 class ColorTextureLayerProgram
;
68 class CompositorWidget
;
70 } // namespace mozilla
75 enum class GLFeature
{
87 EXT_color_buffer_float
,
91 framebuffer_multisample
,
93 framebuffer_object_EXT_OES
,
95 get_integer64_indexed
,
96 get_query_object_i64v
,
100 instanced_non_arrays
,
101 internalformat_query
,
102 invalidate_framebuffer
,
106 occlusion_query_boolean
,
108 packed_depth_stencil
,
116 renderbuffer_color_float
,
117 renderbuffer_color_half_float
,
118 robust_buffer_access_behavior
,
122 seamless_cube_map_opt_in
,
125 standard_derivatives
,
128 texture_3D_compressed
,
130 texture_compression_bptc
,
131 texture_compression_rgtc
,
133 texture_float_linear
,
135 texture_half_float_linear
,
136 texture_non_power_of_two
,
142 uniform_buffer_object
,
143 uniform_matrix_nonsquare
,
148 enum class ContextProfile
: uint8_t {
155 enum class GLRenderer
{
174 MicrosoftBasicRenderDriver
,
179 class GLContext
: public GenericAtomicRefCounted
, public SupportsWeakPtr
{
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
;
197 explicit TlsScope(GLContext
* const gl
, bool invalidate
= false)
198 : mGL(gl
), mWasTlsOk(gl
&& gl
->mUseTLSIsCurrent
) {
201 InvalidateCurrentContext();
203 mGL
->mUseTLSIsCurrent
= true;
209 mGL
->mUseTLSIsCurrent
= mWasTlsOk
;
214 // -----------------------------------------------------------------------------
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
) {
266 return profile
== mProfile
;
270 * Return the version of the context.
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
;
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
356 AMD_compressed_ATC_texture
,
358 ANGLE_framebuffer_blit
,
359 ANGLE_framebuffer_multisample
,
360 ANGLE_instanced_arrays
,
362 ANGLE_provoking_vertex
,
363 ANGLE_texture_compression_dxt3
,
364 ANGLE_texture_compression_dxt5
,
366 APPLE_client_storage
,
368 APPLE_framebuffer_multisample
,
371 APPLE_vertex_array_object
,
372 ARB_ES2_compatibility
,
373 ARB_ES3_compatibility
,
374 ARB_color_buffer_float
,
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
,
394 ARB_seamless_cube_map
,
395 ARB_shader_texture_lod
,
397 ARB_texture_compression
,
398 ARB_texture_compression_bptc
,
399 ARB_texture_compression_rgtc
,
401 ARB_texture_non_power_of_two
,
402 ARB_texture_rectangle
,
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
,
414 EXT_color_buffer_float
,
415 EXT_color_buffer_half_float
,
417 EXT_disjoint_timer_query
,
423 EXT_framebuffer_blit
,
424 EXT_framebuffer_multisample
,
425 EXT_framebuffer_object
,
426 EXT_framebuffer_sRGB
,
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
,
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
,
449 EXT_transform_feedback
,
452 IMG_texture_compression_pvrtc
,
455 KHR_parallel_shader_compile
,
456 KHR_robust_buffer_access_behavior
,
458 KHR_texture_compression_astc_hdr
,
459 KHR_texture_compression_astc_ldr
,
463 NV_geometry_program4
,
466 NV_primitive_restart
,
468 NV_transform_feedback
,
469 NV_transform_feedback2
,
471 OES_EGL_image_external
,
473 OES_compressed_ETC1_RGB8_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
,
483 OES_standard_derivatives
,
487 OES_texture_float_linear
,
488 OES_texture_half_float
,
489 OES_texture_half_float_linear
,
491 OES_vertex_array_object
,
497 bool IsExtensionSupported(GLExtensions aKnownExtension
) const {
498 return mAvailableExtensions
[aKnownExtension
];
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 // -----------------------------------------------------------------------------
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
520 bool IsSupported(GLFeature feature
) const {
521 return mAvailableFeatures
[size_t(feature
)];
524 static const char* GetFeatureName(GLFeature feature
);
527 std::bitset
<size_t(GLFeature::EnumMax
)> mAvailableFeatures
;
530 * Init features regarding OpenGL extension and context version and profile
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 // -----------------------------------------------------------------------------
548 mutable bool mContextLost
= false;
549 mutable GLenum mTopError
= 0;
552 void OnContextLostError() const;
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
;
564 mutable std::stack
<const LocalErrorScope
*> mLocalErrorScopeStack
;
565 mutable UniquePtr
<LocalErrorScope
> mDebugErrorScope
;
567 ////////////////////////////////////
568 // Use this safer option.
571 class LocalErrorScope
{
572 const GLContext
& mGL
;
574 bool mHasBeenChecked
;
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.
585 MOZ_ASSERT(!mHasBeenChecked
);
586 mHasBeenChecked
= true;
588 const auto ret
= mGL
.GetError();
589 if (ret
== LOCAL_GL_CONTEXT_LOST
) return 0;
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
;
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
);
621 static void GLAPIENTRY
StaticDebugCallback(GLenum source
, GLenum type
,
622 GLuint id
, GLenum severity
,
624 const GLchar
* message
,
625 const GLvoid
* userParam
);
627 // -----------------------------------------------------------------------------
628 // Debugging implementation
630 #ifndef MOZ_FUNCTION_NAME
632 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
633 # elif defined(_MSC_VER)
634 # define MOZ_FUNCTION_NAME __FUNCTION__
636 # define MOZ_FUNCTION_NAME \
637 __func__ // defined in C99, supported in various C++ compilers. Just raw
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);
646 # define ANDROID_ONLY_PROFILER_LABEL
649 #define BEFORE_GL_CALL \
650 ANDROID_ONLY_PROFILER_LABEL \
651 if (MOZ_LIKELY(BeforeGLCall(MOZ_FUNCTION_NAME))) { \
655 #define AFTER_GL_CALL \
656 AfterGLCall(MOZ_FUNCTION_NAME); \
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())) {
669 OnImplicitMakeCurrentFailure(funcName
);
674 MOZ_GL_ASSERT(this, IsCurrentImpl());
676 if (MOZ_UNLIKELY(mDebugFlags
)) {
677 BeforeGLCall_Debug(funcName
);
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
;
694 static void AssertNotPassingStackBufferToTheGL(const void* ptr
);
696 #ifdef MOZ_GL_DEBUG_BUILD
698 # define TRACKING_CONTEXT(a) \
700 TrackingContext()->a; \
703 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
704 AssertNotPassingStackBufferToTheGL(ptr)
706 # define ASSERT_SYMBOL_PRESENT(func) \
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", \
713 MOZ_CRASH("GFX: Uninitialized GL function"); \
717 #else // ifdef MOZ_GL_DEBUG_BUILD
719 # define TRACKING_CONTEXT(a) \
722 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
725 # define ASSERT_SYMBOL_PRESENT(func) \
729 #endif // ifdef MOZ_GL_DEBUG_BUILD
731 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
733 void BeforeGLDrawCall() {}
735 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
737 void AfterGLDrawCall() { mHeavyGLCallsSinceLastFlush
= true; }
739 // Do whatever setup is necessary to read from our offscreen FBO, if it's
741 void BeforeGLReadCall() {}
743 // Do whatever tear-down is necessary after reading from our offscreen FBO,
745 void AfterGLReadCall() {}
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
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;
769 void fActiveTexture(GLenum texture
) {
771 mSymbols
.fActiveTexture(texture
);
775 void fAttachShader(GLuint program
, GLuint shader
) {
777 mSymbols
.fAttachShader(program
, shader
);
781 void fBeginQuery(GLenum target
, GLuint id
) {
783 ASSERT_SYMBOL_PRESENT(fBeginQuery
);
784 mSymbols
.fBeginQuery(target
, id
);
788 void fBindAttribLocation(GLuint program
, GLuint index
, const GLchar
* name
) {
790 mSymbols
.fBindAttribLocation(program
, index
, name
);
794 void fBindBuffer(GLenum target
, GLuint buffer
) {
796 mSymbols
.fBindBuffer(target
, buffer
);
800 void fInvalidateFramebuffer(GLenum target
, GLsizei numAttachments
,
801 const GLenum
* attachments
) {
804 ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer
);
805 mSymbols
.fInvalidateFramebuffer(target
, numAttachments
, attachments
);
810 void fInvalidateSubFramebuffer(GLenum target
, GLsizei numAttachments
,
811 const GLenum
* attachments
, GLint x
, GLint y
,
812 GLsizei width
, GLsizei height
) {
815 ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer
);
816 mSymbols
.fInvalidateSubFramebuffer(target
, numAttachments
, attachments
, x
,
822 void fBindTexture(GLenum target
, GLuint texture
) {
824 mSymbols
.fBindTexture(target
, texture
);
828 void fBlendColor(GLfloat red
, GLfloat green
, GLfloat blue
, GLfloat alpha
) {
830 mSymbols
.fBlendColor(red
, green
, blue
, alpha
);
834 void fBlendEquation(GLenum mode
) {
836 mSymbols
.fBlendEquation(mode
);
840 void fBlendEquationSeparate(GLenum modeRGB
, GLenum modeAlpha
) {
842 mSymbols
.fBlendEquationSeparate(modeRGB
, modeAlpha
);
846 void fBlendFunc(GLenum sfactor
, GLenum dfactor
) {
848 mSymbols
.fBlendFunc(sfactor
, dfactor
);
852 void fBlendFuncSeparate(GLenum sfactorRGB
, GLenum dfactorRGB
,
853 GLenum sfactorAlpha
, GLenum dfactorAlpha
) {
855 mSymbols
.fBlendFuncSeparate(sfactorRGB
, dfactorRGB
, sfactorAlpha
,
861 void raw_fBufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
863 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data
);
865 mSymbols
.fBufferData(target
, size
, data
, usage
);
868 mHeavyGLCallsSinceLastFlush
= true;
872 void fBufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
874 raw_fBufferData(target
, size
, data
, usage
);
877 if (WorkAroundDriverBugs() && !data
&& Vendor() == GLVendor::NVIDIA
) {
878 UniquePtr
<char[]> buf
= MakeUnique
<char[]>(1);
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
);
888 mSymbols
.fBufferSubData(target
, offset
, size
, data
);
890 mHeavyGLCallsSinceLastFlush
= true;
894 void raw_fClear(GLbitfield mask
) {
896 mSymbols
.fClear(mask
);
901 void fClear(GLbitfield mask
) {
907 void fClearBufferfi(GLenum buffer
, GLint drawbuffer
, GLfloat depth
,
911 mSymbols
.fClearBufferfi(buffer
, drawbuffer
, depth
, stencil
);
916 void fClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
* value
) {
919 mSymbols
.fClearBufferfv(buffer
, drawbuffer
, value
);
924 void fClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
* value
) {
927 mSymbols
.fClearBufferiv(buffer
, drawbuffer
, value
);
932 void fClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
* value
) {
935 mSymbols
.fClearBufferuiv(buffer
, drawbuffer
, value
);
940 void fClearColor(GLfloat r
, GLfloat g
, GLfloat b
, GLfloat a
) {
942 mSymbols
.fClearColor(r
, g
, b
, a
);
946 void fClearStencil(GLint s
) {
948 mSymbols
.fClearStencil(s
);
952 void fClientActiveTexture(GLenum texture
) {
954 mSymbols
.fClientActiveTexture(texture
);
958 void fColorMask(realGLboolean red
, realGLboolean green
, realGLboolean blue
,
959 realGLboolean alpha
) {
961 mSymbols
.fColorMask(red
, green
, blue
, alpha
);
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
);
970 mSymbols
.fCompressedTexImage2D(target
, level
, internalformat
, width
, height
,
971 border
, imageSize
, pixels
);
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
);
982 mSymbols
.fCompressedTexSubImage2D(target
, level
, xoffset
, yoffset
, width
,
983 height
, format
, imageSize
, pixels
);
985 mHeavyGLCallsSinceLastFlush
= true;
988 void fCopyTexImage2D(GLenum target
, GLint level
, GLenum internalformat
,
989 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
992 void fCopyTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
993 GLint yoffset
, GLint x
, GLint y
, GLsizei width
,
996 raw_fCopyTexSubImage2D(target
, level
, xoffset
, yoffset
, x
, y
, width
,
1001 void fCullFace(GLenum mode
) {
1003 mSymbols
.fCullFace(mode
);
1007 void fDebugMessageCallback(GLDEBUGPROC callback
, const GLvoid
* userParam
) {
1009 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback
);
1010 mSymbols
.fDebugMessageCallback(callback
, userParam
);
1014 void fDebugMessageControl(GLenum source
, GLenum type
, GLenum severity
,
1015 GLsizei count
, const GLuint
* ids
,
1016 realGLboolean enabled
) {
1018 ASSERT_SYMBOL_PRESENT(fDebugMessageControl
);
1019 mSymbols
.fDebugMessageControl(source
, type
, severity
, count
, ids
, enabled
);
1023 void fDebugMessageInsert(GLenum source
, GLenum type
, GLuint id
,
1024 GLenum severity
, GLsizei length
, const GLchar
* buf
) {
1026 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert
);
1027 mSymbols
.fDebugMessageInsert(source
, type
, id
, severity
, length
, buf
);
1031 void fDetachShader(GLuint program
, GLuint shader
) {
1033 mSymbols
.fDetachShader(program
, shader
);
1037 void fDepthFunc(GLenum func
) {
1039 mSymbols
.fDepthFunc(func
);
1043 void fDepthMask(realGLboolean flag
) {
1045 mSymbols
.fDepthMask(flag
);
1049 void fDisable(GLenum capability
) {
1051 mSymbols
.fDisable(capability
);
1055 void fDisableClientState(GLenum capability
) {
1057 mSymbols
.fDisableClientState(capability
);
1061 void fDisableVertexAttribArray(GLuint index
) {
1063 mSymbols
.fDisableVertexAttribArray(index
);
1067 void fDrawBuffer(GLenum mode
) {
1069 mSymbols
.fDrawBuffer(mode
);
1074 void raw_fDrawArrays(GLenum mode
, GLint first
, GLsizei count
) {
1076 mSymbols
.fDrawArrays(mode
, first
, count
);
1080 void raw_fDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1081 const GLvoid
* indices
) {
1083 mSymbols
.fDrawElements(mode
, count
, type
, indices
);
1088 void fDrawArrays(GLenum mode
, GLint first
, GLsizei count
) {
1090 raw_fDrawArrays(mode
, first
, count
);
1094 void fDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1095 const GLvoid
* indices
) {
1097 raw_fDrawElements(mode
, count
, type
, indices
);
1101 void fEnable(GLenum capability
) {
1103 mSymbols
.fEnable(capability
);
1107 void fEnableClientState(GLenum capability
) {
1109 mSymbols
.fEnableClientState(capability
);
1113 void fEnableVertexAttribArray(GLuint index
) {
1115 mSymbols
.fEnableVertexAttribArray(index
);
1119 void fEndQuery(GLenum target
) {
1121 ASSERT_SYMBOL_PRESENT(fEndQuery
);
1122 mSymbols
.fEndQuery(target
);
1131 mHeavyGLCallsSinceLastFlush
= false;
1138 mHeavyGLCallsSinceLastFlush
= false;
1141 void fFrontFace(GLenum face
) {
1143 mSymbols
.fFrontFace(face
);
1147 void fGetActiveAttrib(GLuint program
, GLuint index
, GLsizei maxLength
,
1148 GLsizei
* length
, GLint
* size
, GLenum
* type
,
1151 mSymbols
.fGetActiveAttrib(program
, index
, maxLength
, length
, size
, type
,
1157 void fGetActiveUniform(GLuint program
, GLuint index
, GLsizei maxLength
,
1158 GLsizei
* length
, GLint
* size
, GLenum
* type
,
1161 mSymbols
.fGetActiveUniform(program
, index
, maxLength
, length
, size
, type
,
1167 void fGetAttachedShaders(GLuint program
, GLsizei maxCount
, GLsizei
* count
,
1170 mSymbols
.fGetAttachedShaders(program
, maxCount
, count
, shaders
);
1175 GLint
fGetAttribLocation(GLuint program
, const GLchar
* name
) {
1178 retval
= mSymbols
.fGetAttribLocation(program
, name
);
1185 void raw_fGetIntegerv(GLenum pname
, GLint
* params
) const {
1187 mSymbols
.fGetIntegerv(pname
, params
);
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.");
1209 fGetIntegerv(pname
, (GLint
*)&ret
);
1213 void fGetFloatv(GLenum pname
, GLfloat
* params
) const {
1215 mSymbols
.fGetFloatv(pname
, params
);
1220 void fGetBooleanv(GLenum pname
, realGLboolean
* params
) const {
1222 mSymbols
.fGetBooleanv(pname
, params
);
1227 void fGetBufferParameteriv(GLenum target
, GLenum pname
, GLint
* params
) {
1229 mSymbols
.fGetBufferParameteriv(target
, pname
, params
);
1234 GLuint
fGetDebugMessageLog(GLuint count
, GLsizei bufsize
, GLenum
* sources
,
1235 GLenum
* types
, GLuint
* ids
, GLenum
* severities
,
1236 GLsizei
* lengths
, GLchar
* messageLog
) {
1239 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog
);
1240 ret
= mSymbols
.fGetDebugMessageLog(count
, bufsize
, sources
, types
, ids
,
1241 severities
, lengths
, messageLog
);
1247 void fGetPointerv(GLenum pname
, GLvoid
** params
) {
1249 ASSERT_SYMBOL_PRESENT(fGetPointerv
);
1250 mSymbols
.fGetPointerv(pname
, params
);
1255 void fGetObjectLabel(GLenum identifier
, GLuint name
, GLsizei bufSize
,
1256 GLsizei
* length
, GLchar
* label
) {
1258 ASSERT_SYMBOL_PRESENT(fGetObjectLabel
);
1259 mSymbols
.fGetObjectLabel(identifier
, name
, bufSize
, length
, label
);
1264 void fGetObjectPtrLabel(const GLvoid
* ptr
, GLsizei bufSize
, GLsizei
* length
,
1267 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel
);
1268 mSymbols
.fGetObjectPtrLabel(ptr
, bufSize
, length
, label
);
1273 void fGenerateMipmap(GLenum target
) {
1275 mSymbols
.fGenerateMipmap(target
);
1279 void fGetProgramiv(GLuint program
, GLenum pname
, GLint
* param
) {
1281 mSymbols
.fGetProgramiv(program
, pname
, param
);
1286 void fGetProgramInfoLog(GLuint program
, GLsizei bufSize
, GLsizei
* length
,
1289 mSymbols
.fGetProgramInfoLog(program
, bufSize
, length
, infoLog
);
1294 void fTexParameteri(GLenum target
, GLenum pname
, GLint param
) {
1296 mSymbols
.fTexParameteri(target
, pname
, param
);
1300 void fTexParameteriv(GLenum target
, GLenum pname
, const GLint
* params
) {
1302 mSymbols
.fTexParameteriv(target
, pname
, params
);
1306 void fTexParameterf(GLenum target
, GLenum pname
, GLfloat param
) {
1308 mSymbols
.fTexParameterf(target
, pname
, param
);
1312 const GLubyte
* fGetString(GLenum name
) {
1313 const GLubyte
* result
= nullptr;
1315 result
= mSymbols
.fGetString(name
);
1321 void fGetTexImage(GLenum target
, GLint level
, GLenum format
, GLenum type
,
1324 ASSERT_SYMBOL_PRESENT(fGetTexImage
);
1325 mSymbols
.fGetTexImage(target
, level
, format
, type
, img
);
1330 void fGetTexLevelParameteriv(GLenum target
, GLint level
, GLenum pname
,
1333 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv
);
1334 mSymbols
.fGetTexLevelParameteriv(target
, level
, pname
, params
);
1339 void fGetTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* params
) {
1341 mSymbols
.fGetTexParameterfv(target
, pname
, params
);
1346 void fGetTexParameteriv(GLenum target
, GLenum pname
, GLint
* params
) {
1348 mSymbols
.fGetTexParameteriv(target
, pname
, params
);
1353 void fGetUniformfv(GLuint program
, GLint location
, GLfloat
* params
) {
1355 mSymbols
.fGetUniformfv(program
, location
, params
);
1360 void fGetUniformiv(GLuint program
, GLint location
, GLint
* params
) {
1362 mSymbols
.fGetUniformiv(program
, location
, params
);
1367 void fGetUniformuiv(GLuint program
, GLint location
, GLuint
* params
) {
1369 ASSERT_SYMBOL_PRESENT(fGetUniformuiv
);
1370 mSymbols
.fGetUniformuiv(program
, location
, params
);
1375 GLint
fGetUniformLocation(GLuint programObj
, const GLchar
* name
) {
1378 retval
= mSymbols
.fGetUniformLocation(programObj
, name
);
1384 void fGetVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* retval
) {
1386 mSymbols
.fGetVertexAttribfv(index
, pname
, retval
);
1391 void fGetVertexAttribiv(GLuint index
, GLenum pname
, GLint
* retval
) {
1393 mSymbols
.fGetVertexAttribiv(index
, pname
, retval
);
1398 void fGetVertexAttribPointerv(GLuint index
, GLenum pname
, GLvoid
** retval
) {
1400 mSymbols
.fGetVertexAttribPointerv(index
, pname
, retval
);
1405 void fHint(GLenum target
, GLenum mode
) {
1407 mSymbols
.fHint(target
, mode
);
1411 realGLboolean
fIsBuffer(GLuint buffer
) {
1412 realGLboolean retval
= false;
1414 retval
= mSymbols
.fIsBuffer(buffer
);
1420 realGLboolean
fIsEnabled(GLenum capability
) {
1421 realGLboolean retval
= false;
1423 retval
= mSymbols
.fIsEnabled(capability
);
1428 void SetEnabled(const GLenum cap
, const bool val
) {
1436 bool PushEnabled(const GLenum cap
, const bool newVal
) {
1437 const bool oldVal
= fIsEnabled(cap
);
1438 if (oldVal
!= newVal
) {
1439 SetEnabled(cap
, newVal
);
1444 realGLboolean
fIsProgram(GLuint program
) {
1445 realGLboolean retval
= false;
1447 retval
= mSymbols
.fIsProgram(program
);
1452 realGLboolean
fIsShader(GLuint shader
) {
1453 realGLboolean retval
= false;
1455 retval
= mSymbols
.fIsShader(shader
);
1460 realGLboolean
fIsTexture(GLuint texture
) {
1461 realGLboolean retval
= false;
1463 retval
= mSymbols
.fIsTexture(texture
);
1468 void fLineWidth(GLfloat width
) {
1470 mSymbols
.fLineWidth(width
);
1474 void fLinkProgram(GLuint program
) {
1476 mSymbols
.fLinkProgram(program
);
1480 void fObjectLabel(GLenum identifier
, GLuint name
, GLsizei length
,
1481 const GLchar
* label
) {
1483 ASSERT_SYMBOL_PRESENT(fObjectLabel
);
1484 mSymbols
.fObjectLabel(identifier
, name
, length
, label
);
1488 void fObjectPtrLabel(const GLvoid
* ptr
, GLsizei length
, const GLchar
* label
) {
1490 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel
);
1491 mSymbols
.fObjectPtrLabel(ptr
, length
, label
);
1495 void fLoadIdentity() {
1497 mSymbols
.fLoadIdentity();
1501 void fLoadMatrixf(const GLfloat
* matrix
) {
1503 mSymbols
.fLoadMatrixf(matrix
);
1507 void fMatrixMode(GLenum mode
) {
1509 mSymbols
.fMatrixMode(mode
);
1513 void fPixelStorei(GLenum pname
, GLint param
) {
1515 mSymbols
.fPixelStorei(pname
, param
);
1519 void fTextureRangeAPPLE(GLenum target
, GLsizei length
, GLvoid
* pointer
) {
1520 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer
);
1522 mSymbols
.fTextureRangeAPPLE(target
, length
, pointer
);
1526 void fPointParameterf(GLenum pname
, GLfloat param
) {
1528 mSymbols
.fPointParameterf(pname
, param
);
1532 void fPolygonMode(GLenum face
, GLenum mode
) {
1534 mSymbols
.fPolygonMode(face
, mode
);
1538 void fPolygonOffset(GLfloat factor
, GLfloat bias
) {
1540 mSymbols
.fPolygonOffset(factor
, bias
);
1544 void fPopDebugGroup() {
1546 ASSERT_SYMBOL_PRESENT(fPopDebugGroup
);
1547 mSymbols
.fPopDebugGroup();
1551 void fPushDebugGroup(GLenum source
, GLuint id
, GLsizei length
,
1552 const GLchar
* message
) {
1554 ASSERT_SYMBOL_PRESENT(fPushDebugGroup
);
1555 mSymbols
.fPushDebugGroup(source
, id
, length
, message
);
1559 void fReadBuffer(GLenum mode
) {
1561 mSymbols
.fReadBuffer(mode
);
1565 void raw_fReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1566 GLenum format
, GLenum type
, GLvoid
* pixels
) {
1568 mSymbols
.fReadPixels(x
, y
, width
, height
, format
, type
, pixels
);
1571 mHeavyGLCallsSinceLastFlush
= true;
1574 void fReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1575 GLenum format
, GLenum type
, GLvoid
* pixels
);
1578 void fSampleCoverage(GLclampf value
, realGLboolean invert
) {
1580 mSymbols
.fSampleCoverage(value
, invert
);
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
) {
1589 mScissorRect
[0] = x
;
1590 mScissorRect
[1] = y
;
1591 mScissorRect
[2] = width
;
1592 mScissorRect
[3] = height
;
1594 mSymbols
.fScissor(x
, y
, width
, height
);
1598 void fStencilFunc(GLenum func
, GLint reference
, GLuint mask
) {
1600 mSymbols
.fStencilFunc(func
, reference
, mask
);
1604 void fStencilFuncSeparate(GLenum frontfunc
, GLenum backfunc
, GLint reference
,
1607 mSymbols
.fStencilFuncSeparate(frontfunc
, backfunc
, reference
, mask
);
1611 void fStencilMask(GLuint mask
) {
1613 mSymbols
.fStencilMask(mask
);
1617 void fStencilMaskSeparate(GLenum face
, GLuint mask
) {
1619 mSymbols
.fStencilMaskSeparate(face
, mask
);
1623 void fStencilOp(GLenum fail
, GLenum zfail
, GLenum zpass
) {
1625 mSymbols
.fStencilOp(fail
, zfail
, zpass
);
1629 void fStencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
1632 mSymbols
.fStencilOpSeparate(face
, sfail
, dpfail
, dppass
);
1636 void fTexGeni(GLenum coord
, GLenum pname
, GLint param
) {
1638 mSymbols
.fTexGeni(coord
, pname
, param
);
1642 void fTexGenf(GLenum coord
, GLenum pname
, GLfloat param
) {
1644 mSymbols
.fTexGenf(coord
, pname
, param
);
1648 void fTexGenfv(GLenum coord
, GLenum pname
, const GLfloat
* params
) {
1650 mSymbols
.fTexGenfv(coord
, pname
, params
);
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
);
1660 mSymbols
.fTexImage2D(target
, level
, internalformat
, width
, height
, border
,
1661 format
, type
, pixels
);
1663 mHeavyGLCallsSinceLastFlush
= true;
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
);
1676 mSymbols
.fTexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
1677 format
, type
, pixels
);
1679 mHeavyGLCallsSinceLastFlush
= true;
1682 void fUniform1f(GLint location
, GLfloat v0
) {
1684 mSymbols
.fUniform1f(location
, v0
);
1688 void fUniform1fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1690 mSymbols
.fUniform1fv(location
, count
, value
);
1694 void fUniform1i(GLint location
, GLint v0
) {
1696 mSymbols
.fUniform1i(location
, v0
);
1700 void fUniform1iv(GLint location
, GLsizei count
, const GLint
* value
) {
1702 mSymbols
.fUniform1iv(location
, count
, value
);
1706 void fUniform2f(GLint location
, GLfloat v0
, GLfloat v1
) {
1708 mSymbols
.fUniform2f(location
, v0
, v1
);
1712 void fUniform2fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1714 mSymbols
.fUniform2fv(location
, count
, value
);
1718 void fUniform2i(GLint location
, GLint v0
, GLint v1
) {
1720 mSymbols
.fUniform2i(location
, v0
, v1
);
1724 void fUniform2iv(GLint location
, GLsizei count
, const GLint
* value
) {
1726 mSymbols
.fUniform2iv(location
, count
, value
);
1730 void fUniform3f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
) {
1732 mSymbols
.fUniform3f(location
, v0
, v1
, v2
);
1736 void fUniform3fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1738 mSymbols
.fUniform3fv(location
, count
, value
);
1742 void fUniform3i(GLint location
, GLint v0
, GLint v1
, GLint v2
) {
1744 mSymbols
.fUniform3i(location
, v0
, v1
, v2
);
1748 void fUniform3iv(GLint location
, GLsizei count
, const GLint
* value
) {
1750 mSymbols
.fUniform3iv(location
, count
, value
);
1754 void fUniform4f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
1757 mSymbols
.fUniform4f(location
, v0
, v1
, v2
, v3
);
1761 void fUniform4fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1763 mSymbols
.fUniform4fv(location
, count
, value
);
1767 void fUniform4i(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
) {
1769 mSymbols
.fUniform4i(location
, v0
, v1
, v2
, v3
);
1773 void fUniform4iv(GLint location
, GLsizei count
, const GLint
* value
) {
1775 mSymbols
.fUniform4iv(location
, count
, value
);
1779 void fUniformMatrix2fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1780 const GLfloat
* value
) {
1782 mSymbols
.fUniformMatrix2fv(location
, count
, transpose
, value
);
1786 void fUniformMatrix2x3fv(GLint location
, GLsizei count
,
1787 realGLboolean transpose
, const GLfloat
* value
) {
1789 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv
);
1790 mSymbols
.fUniformMatrix2x3fv(location
, count
, transpose
, value
);
1794 void fUniformMatrix2x4fv(GLint location
, GLsizei count
,
1795 realGLboolean transpose
, const GLfloat
* value
) {
1797 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv
);
1798 mSymbols
.fUniformMatrix2x4fv(location
, count
, transpose
, value
);
1802 void fUniformMatrix3fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1803 const GLfloat
* value
) {
1805 mSymbols
.fUniformMatrix3fv(location
, count
, transpose
, value
);
1809 void fUniformMatrix3x2fv(GLint location
, GLsizei count
,
1810 realGLboolean transpose
, const GLfloat
* value
) {
1812 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv
);
1813 mSymbols
.fUniformMatrix3x2fv(location
, count
, transpose
, value
);
1817 void fUniformMatrix3x4fv(GLint location
, GLsizei count
,
1818 realGLboolean transpose
, const GLfloat
* value
) {
1820 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv
);
1821 mSymbols
.fUniformMatrix3x4fv(location
, count
, transpose
, value
);
1825 void fUniformMatrix4fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1826 const GLfloat
* value
) {
1828 mSymbols
.fUniformMatrix4fv(location
, count
, transpose
, value
);
1832 void fUniformMatrix4x2fv(GLint location
, GLsizei count
,
1833 realGLboolean transpose
, const GLfloat
* value
) {
1835 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv
);
1836 mSymbols
.fUniformMatrix4x2fv(location
, count
, transpose
, value
);
1840 void fUniformMatrix4x3fv(GLint location
, GLsizei count
,
1841 realGLboolean transpose
, const GLfloat
* value
) {
1843 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv
);
1844 mSymbols
.fUniformMatrix4x3fv(location
, count
, transpose
, value
);
1848 void fUseProgram(GLuint program
) {
1850 mSymbols
.fUseProgram(program
);
1854 void fValidateProgram(GLuint program
) {
1856 mSymbols
.fValidateProgram(program
);
1860 void fVertexAttribPointer(GLuint index
, GLint size
, GLenum type
,
1861 realGLboolean normalized
, GLsizei stride
,
1862 const GLvoid
* pointer
) {
1864 mSymbols
.fVertexAttribPointer(index
, size
, type
, normalized
, stride
,
1869 void fVertexAttrib1f(GLuint index
, GLfloat x
) {
1871 mSymbols
.fVertexAttrib1f(index
, x
);
1875 void fVertexAttrib2f(GLuint index
, GLfloat x
, GLfloat y
) {
1877 mSymbols
.fVertexAttrib2f(index
, x
, y
);
1881 void fVertexAttrib3f(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
) {
1883 mSymbols
.fVertexAttrib3f(index
, x
, y
, z
);
1887 void fVertexAttrib4f(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
,
1890 mSymbols
.fVertexAttrib4f(index
, x
, y
, z
, w
);
1894 void fVertexAttrib1fv(GLuint index
, const GLfloat
* v
) {
1896 mSymbols
.fVertexAttrib1fv(index
, v
);
1900 void fVertexAttrib2fv(GLuint index
, const GLfloat
* v
) {
1902 mSymbols
.fVertexAttrib2fv(index
, v
);
1906 void fVertexAttrib3fv(GLuint index
, const GLfloat
* v
) {
1908 mSymbols
.fVertexAttrib3fv(index
, v
);
1912 void fVertexAttrib4fv(GLuint index
, const GLfloat
* v
) {
1914 mSymbols
.fVertexAttrib4fv(index
, v
);
1918 void fVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
1919 const GLvoid
* pointer
) {
1921 mSymbols
.fVertexPointer(size
, type
, stride
, pointer
);
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
) {
1930 mViewportRect
[0] = x
;
1931 mViewportRect
[1] = y
;
1932 mViewportRect
[2] = width
;
1933 mViewportRect
[3] = height
;
1935 mSymbols
.fViewport(x
, y
, width
, height
);
1939 void fCompileShader(GLuint shader
) {
1941 mSymbols
.fCompileShader(shader
);
1946 friend class SharedSurface_IOSurface
;
1948 void raw_fCopyTexImage2D(GLenum target
, GLint level
, GLenum internalformat
,
1949 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1952 mSymbols
.fCopyTexImage2D(target
, level
, internalformat
, x
, y
, width
, height
,
1957 void raw_fCopyTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
1958 GLint yoffset
, GLint x
, GLint y
, GLsizei width
,
1961 mSymbols
.fCopyTexSubImage2D(target
, level
, xoffset
, yoffset
, x
, y
, width
,
1967 void fGetShaderiv(GLuint shader
, GLenum pname
, GLint
* param
) {
1969 mSymbols
.fGetShaderiv(shader
, pname
, param
);
1974 void fGetShaderInfoLog(GLuint shader
, GLsizei bufSize
, GLsizei
* length
,
1977 mSymbols
.fGetShaderInfoLog(shader
, bufSize
, length
, infoLog
);
1983 void raw_fGetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
,
1984 GLint
* range
, GLint
* precision
) {
1985 MOZ_ASSERT(IsGLES());
1988 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat
);
1989 mSymbols
.fGetShaderPrecisionFormat(shadertype
, precisiontype
, range
,
1996 void fGetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
,
1997 GLint
* range
, GLint
* precision
) {
1999 raw_fGetShaderPrecisionFormat(shadertype
, precisiontype
, range
,
2002 // Fall back to automatic values because almost all desktop hardware
2003 // supports the OpenGL standard precisions.
2004 GetShaderPrecisionFormatNonES2(shadertype
, precisiontype
, range
,
2009 void fGetShaderSource(GLint obj
, GLsizei maxLength
, GLsizei
* length
,
2012 mSymbols
.fGetShaderSource(obj
, maxLength
, length
, source
);
2017 void fShaderSource(GLuint shader
, GLsizei count
, const GLchar
* const* strings
,
2018 const GLint
* lengths
) {
2020 mSymbols
.fShaderSource(shader
, count
, strings
, lengths
);
2025 mutable GLuint mCachedDrawFb
= 0;
2026 mutable GLuint mCachedReadFb
= 0;
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
));
2039 case LOCAL_GL_FRAMEBUFFER
:
2040 if (mCachedDrawFb
== fb
&& mCachedReadFb
== fb
) return;
2042 case LOCAL_GL_DRAW_FRAMEBUFFER
:
2043 if (mCachedDrawFb
== fb
) return;
2045 case LOCAL_GL_READ_FRAMEBUFFER
:
2046 if (mCachedReadFb
== fb
) return;
2052 mSymbols
.fBindFramebuffer(target
, fb
);
2056 case LOCAL_GL_FRAMEBUFFER
:
2060 case LOCAL_GL_DRAW_FRAMEBUFFER
:
2063 case LOCAL_GL_READ_FRAMEBUFFER
:
2069 void fBindRenderbuffer(GLenum target
, GLuint renderbuffer
) {
2071 mSymbols
.fBindRenderbuffer(target
, renderbuffer
);
2075 GLenum
fCheckFramebufferStatus(GLenum target
) {
2078 retval
= mSymbols
.fCheckFramebufferStatus(target
);
2084 void fFramebufferRenderbuffer(GLenum target
, GLenum attachmentPoint
,
2085 GLenum renderbufferTarget
,
2086 GLuint renderbuffer
) {
2088 mSymbols
.fFramebufferRenderbuffer(target
, attachmentPoint
,
2089 renderbufferTarget
, renderbuffer
);
2093 void fFramebufferTexture2D(GLenum target
, GLenum attachmentPoint
,
2094 GLenum textureTarget
, GLuint texture
,
2097 mSymbols
.fFramebufferTexture2D(target
, attachmentPoint
, textureTarget
,
2102 void fFramebufferTextureLayer(GLenum target
, GLenum attachment
,
2103 GLuint texture
, GLint level
, GLint layer
) {
2105 ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer
);
2106 mSymbols
.fFramebufferTextureLayer(target
, attachment
, texture
, level
,
2111 void fGetFramebufferAttachmentParameteriv(GLenum target
, GLenum attachment
,
2112 GLenum pname
, GLint
* value
) {
2114 mSymbols
.fGetFramebufferAttachmentParameteriv(target
, attachment
, pname
,
2120 void fGetRenderbufferParameteriv(GLenum target
, GLenum pname
, GLint
* value
) {
2122 mSymbols
.fGetRenderbufferParameteriv(target
, pname
, value
);
2127 realGLboolean
fIsFramebuffer(GLuint framebuffer
) {
2128 realGLboolean retval
= false;
2130 retval
= mSymbols
.fIsFramebuffer(framebuffer
);
2137 realGLboolean
fIsRenderbuffer(GLuint renderbuffer
) {
2138 realGLboolean retval
= false;
2140 retval
= mSymbols
.fIsRenderbuffer(renderbuffer
);
2146 void fRenderbufferStorage(GLenum target
, GLenum internalFormat
, GLsizei width
,
2149 mSymbols
.fRenderbufferStorage(target
, internalFormat
, width
, height
);
2154 void raw_fDepthRange(GLclampf a
, GLclampf b
) {
2155 MOZ_ASSERT(!IsGLES());
2158 ASSERT_SYMBOL_PRESENT(fDepthRange
);
2159 mSymbols
.fDepthRange(a
, b
);
2163 void raw_fDepthRangef(GLclampf a
, GLclampf b
) {
2164 MOZ_ASSERT(IsGLES());
2167 ASSERT_SYMBOL_PRESENT(fDepthRangef
);
2168 mSymbols
.fDepthRangef(a
, b
);
2172 void raw_fClearDepth(GLclampf v
) {
2173 MOZ_ASSERT(!IsGLES());
2176 ASSERT_SYMBOL_PRESENT(fClearDepth
);
2177 mSymbols
.fClearDepth(v
);
2181 void raw_fClearDepthf(GLclampf v
) {
2182 MOZ_ASSERT(IsGLES());
2185 ASSERT_SYMBOL_PRESENT(fClearDepthf
);
2186 mSymbols
.fClearDepthf(v
);
2191 void fDepthRange(GLclampf a
, GLclampf b
) {
2193 raw_fDepthRangef(a
, b
);
2195 raw_fDepthRange(a
, b
);
2199 void fClearDepth(GLclampf v
) {
2201 raw_fClearDepthf(v
);
2207 void* fMapBuffer(GLenum target
, GLenum access
) {
2208 void* ret
= nullptr;
2210 ASSERT_SYMBOL_PRESENT(fMapBuffer
);
2211 ret
= mSymbols
.fMapBuffer(target
, access
);
2217 realGLboolean
fUnmapBuffer(GLenum target
) {
2218 realGLboolean ret
= false;
2220 ASSERT_SYMBOL_PRESENT(fUnmapBuffer
);
2221 ret
= mSymbols
.fUnmapBuffer(target
);
2227 GLuint
raw_fCreateProgram() {
2230 ret
= mSymbols
.fCreateProgram();
2235 GLuint
raw_fCreateShader(GLenum t
) {
2238 ret
= mSymbols
.fCreateShader(t
);
2243 void raw_fGenBuffers(GLsizei n
, GLuint
* names
) {
2245 mSymbols
.fGenBuffers(n
, names
);
2250 void raw_fGenFramebuffers(GLsizei n
, GLuint
* names
) {
2252 mSymbols
.fGenFramebuffers(n
, names
);
2257 void raw_fGenRenderbuffers(GLsizei n
, GLuint
* names
) {
2259 mSymbols
.fGenRenderbuffers(n
, names
);
2264 void raw_fGenTextures(GLsizei n
, GLuint
* names
) {
2266 mSymbols
.fGenTextures(n
, names
);
2272 GLuint
fCreateProgram() {
2273 GLuint ret
= raw_fCreateProgram();
2274 TRACKING_CONTEXT(CreatedProgram(this, ret
));
2278 GLuint
fCreateShader(GLenum t
) {
2279 GLuint ret
= raw_fCreateShader(t
);
2280 TRACKING_CONTEXT(CreatedShader(this, 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
));
2305 void raw_fDeleteProgram(GLuint program
) {
2307 mSymbols
.fDeleteProgram(program
);
2311 void raw_fDeleteShader(GLuint shader
) {
2313 mSymbols
.fDeleteShader(shader
);
2317 void raw_fDeleteBuffers(GLsizei n
, const GLuint
* names
) {
2319 mSymbols
.fDeleteBuffers(n
, names
);
2323 void raw_fDeleteFramebuffers(GLsizei n
, const GLuint
* names
) {
2325 mSymbols
.fDeleteFramebuffers(n
, names
);
2328 for (const auto i
: IntegerRange(n
)) {
2329 const auto fb
= names
[i
];
2330 if (mCachedDrawFb
== fb
) {
2333 if (mCachedReadFb
== fb
) {
2339 void raw_fDeleteRenderbuffers(GLsizei n
, const GLuint
* names
) {
2341 mSymbols
.fDeleteRenderbuffers(n
, names
);
2345 void raw_fDeleteTextures(GLsizei n
, const GLuint
* names
) {
2347 mSymbols
.fDeleteTextures(n
, names
);
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
) {
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.
2382 raw_fDeleteTextures(n
, names
);
2383 TRACKING_CONTEXT(DeletedTextures(this, n
, names
));
2386 // -----------------------------------------------------------------------------
2387 // Extension ARB_sync (GL)
2389 GLsync
fFenceSync(GLenum condition
, GLbitfield flags
) {
2392 ASSERT_SYMBOL_PRESENT(fFenceSync
);
2393 ret
= mSymbols
.fFenceSync(condition
, flags
);
2399 realGLboolean
fIsSync(GLsync sync
) {
2400 realGLboolean ret
= false;
2402 ASSERT_SYMBOL_PRESENT(fIsSync
);
2403 ret
= mSymbols
.fIsSync(sync
);
2409 void fDeleteSync(GLsync sync
) {
2411 ASSERT_SYMBOL_PRESENT(fDeleteSync
);
2412 mSymbols
.fDeleteSync(sync
);
2416 GLenum
fClientWaitSync(GLsync sync
, GLbitfield flags
, GLuint64 timeout
) {
2419 ASSERT_SYMBOL_PRESENT(fClientWaitSync
);
2420 ret
= mSymbols
.fClientWaitSync(sync
, flags
, timeout
);
2426 void fWaitSync(GLsync sync
, GLbitfield flags
, GLuint64 timeout
) {
2428 ASSERT_SYMBOL_PRESENT(fWaitSync
);
2429 mSymbols
.fWaitSync(sync
, flags
, timeout
);
2433 void fGetInteger64v(GLenum pname
, GLint64
* params
) {
2435 ASSERT_SYMBOL_PRESENT(fGetInteger64v
);
2436 mSymbols
.fGetInteger64v(pname
, params
);
2440 void fGetSynciv(GLsync sync
, GLenum pname
, GLsizei bufSize
, GLsizei
* length
,
2443 ASSERT_SYMBOL_PRESENT(fGetSynciv
);
2444 mSymbols
.fGetSynciv(sync
, pname
, bufSize
, length
, values
);
2449 // -----------------------------------------------------------------------------
2450 // Extension OES_EGL_image (GLES)
2452 void fEGLImageTargetTexture2D(GLenum target
, GLeglImage image
) {
2454 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D
);
2455 mSymbols
.fEGLImageTargetTexture2D(target
, image
);
2457 mHeavyGLCallsSinceLastFlush
= true;
2460 void fEGLImageTargetRenderbufferStorage(GLenum target
, GLeglImage image
) {
2462 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage
);
2463 mSymbols
.fEGLImageTargetRenderbufferStorage(target
, image
);
2467 // -----------------------------------------------------------------------------
2468 // Package XXX_bind_buffer_offset
2470 void fBindBufferOffset(GLenum target
, GLuint index
, GLuint buffer
,
2473 ASSERT_SYMBOL_PRESENT(fBindBufferOffset
);
2474 mSymbols
.fBindBufferOffset(target
, index
, buffer
, offset
);
2478 // -----------------------------------------------------------------------------
2479 // Package XXX_draw_buffers
2481 void fDrawBuffers(GLsizei n
, const GLenum
* bufs
) {
2483 ASSERT_SYMBOL_PRESENT(fDrawBuffers
);
2484 mSymbols
.fDrawBuffers(n
, bufs
);
2488 // -----------------------------------------------------------------------------
2489 // Package XXX_draw_instanced
2491 void fDrawArraysInstanced(GLenum mode
, GLint first
, GLsizei count
,
2492 GLsizei primcount
) {
2494 raw_fDrawArraysInstanced(mode
, first
, count
, primcount
);
2498 void fDrawElementsInstanced(GLenum mode
, GLsizei count
, GLenum type
,
2499 const GLvoid
* indices
, GLsizei primcount
) {
2501 raw_fDrawElementsInstanced(mode
, count
, type
, indices
, primcount
);
2506 void raw_fDrawArraysInstanced(GLenum mode
, GLint first
, GLsizei count
,
2507 GLsizei primcount
) {
2509 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced
);
2510 mSymbols
.fDrawArraysInstanced(mode
, first
, count
, primcount
);
2514 void raw_fDrawElementsInstanced(GLenum mode
, GLsizei count
, GLenum type
,
2515 const GLvoid
* indices
, GLsizei primcount
) {
2517 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced
);
2518 mSymbols
.fDrawElementsInstanced(mode
, count
, type
, indices
, primcount
);
2522 // -----------------------------------------------------------------------------
2523 // Package XXX_framebuffer_blit
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
) {
2531 raw_fBlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
, dstY0
, dstX1
, dstY1
,
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
) {
2542 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer
);
2543 mSymbols
.fBlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
, dstY0
, dstX1
,
2544 dstY1
, mask
, filter
);
2548 // -----------------------------------------------------------------------------
2549 // Package XXX_framebuffer_multisample
2551 void fRenderbufferStorageMultisample(GLenum target
, GLsizei samples
,
2552 GLenum internalFormat
, GLsizei width
,
2555 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample
);
2556 mSymbols
.fRenderbufferStorageMultisample(target
, samples
, internalFormat
,
2561 // -----------------------------------------------------------------------------
2562 // GL 3.0, GL ES 3.0 & EXT_gpu_shader4
2564 void fGetVertexAttribIiv(GLuint index
, GLenum pname
, GLint
* params
) {
2565 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv
);
2567 mSymbols
.fGetVertexAttribIiv(index
, pname
, params
);
2572 void fGetVertexAttribIuiv(GLuint index
, GLenum pname
, GLuint
* params
) {
2573 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv
);
2575 mSymbols
.fGetVertexAttribIuiv(index
, pname
, params
);
2580 void fVertexAttribI4i(GLuint index
, GLint x
, GLint y
, GLint z
, GLint w
) {
2582 ASSERT_SYMBOL_PRESENT(fVertexAttribI4i
);
2583 mSymbols
.fVertexAttribI4i(index
, x
, y
, z
, w
);
2587 void fVertexAttribI4iv(GLuint index
, const GLint
* v
) {
2589 ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv
);
2590 mSymbols
.fVertexAttribI4iv(index
, v
);
2594 void fVertexAttribI4ui(GLuint index
, GLuint x
, GLuint y
, GLuint z
, GLuint w
) {
2596 ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui
);
2597 mSymbols
.fVertexAttribI4ui(index
, x
, y
, z
, w
);
2601 void fVertexAttribI4uiv(GLuint index
, const GLuint
* v
) {
2603 ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv
);
2604 mSymbols
.fVertexAttribI4uiv(index
, v
);
2608 void fVertexAttribIPointer(GLuint index
, GLint size
, GLenum type
,
2609 GLsizei stride
, const GLvoid
* offset
) {
2611 ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer
);
2612 mSymbols
.fVertexAttribIPointer(index
, size
, type
, stride
, offset
);
2616 void fUniform1ui(GLint location
, GLuint v0
) {
2618 ASSERT_SYMBOL_PRESENT(fUniform1ui
);
2619 mSymbols
.fUniform1ui(location
, v0
);
2623 void fUniform2ui(GLint location
, GLuint v0
, GLuint v1
) {
2625 ASSERT_SYMBOL_PRESENT(fUniform2ui
);
2626 mSymbols
.fUniform2ui(location
, v0
, v1
);
2630 void fUniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
) {
2632 ASSERT_SYMBOL_PRESENT(fUniform3ui
);
2633 mSymbols
.fUniform3ui(location
, v0
, v1
, v2
);
2637 void fUniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
) {
2639 ASSERT_SYMBOL_PRESENT(fUniform4ui
);
2640 mSymbols
.fUniform4ui(location
, v0
, v1
, v2
, v3
);
2644 void fUniform1uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2646 ASSERT_SYMBOL_PRESENT(fUniform1uiv
);
2647 mSymbols
.fUniform1uiv(location
, count
, value
);
2651 void fUniform2uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2653 ASSERT_SYMBOL_PRESENT(fUniform2uiv
);
2654 mSymbols
.fUniform2uiv(location
, count
, value
);
2658 void fUniform3uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2660 ASSERT_SYMBOL_PRESENT(fUniform3uiv
);
2661 mSymbols
.fUniform3uiv(location
, count
, value
);
2665 void fUniform4uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2667 ASSERT_SYMBOL_PRESENT(fUniform4uiv
);
2668 mSymbols
.fUniform4uiv(location
, count
, value
);
2672 GLint
fGetFragDataLocation(GLuint program
, const GLchar
* name
) {
2675 ASSERT_SYMBOL_PRESENT(fGetFragDataLocation
);
2676 result
= mSymbols
.fGetFragDataLocation(program
, name
);
2682 // -----------------------------------------------------------------------------
2683 // Package XXX_instanced_arrays
2685 void fVertexAttribDivisor(GLuint index
, GLuint divisor
) {
2687 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor
);
2688 mSymbols
.fVertexAttribDivisor(index
, divisor
);
2692 // -----------------------------------------------------------------------------
2693 // Feature internalformat_query
2695 void fGetInternalformativ(GLenum target
, GLenum internalformat
, GLenum pname
,
2696 GLsizei bufSize
, GLint
* params
) {
2698 ASSERT_SYMBOL_PRESENT(fGetInternalformativ
);
2699 mSymbols
.fGetInternalformativ(target
, internalformat
, pname
, bufSize
,
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
2714 void fQueryCounter(GLuint id
, GLenum target
) {
2716 ASSERT_SYMBOL_PRESENT(fQueryCounter
);
2717 mSymbols
.fQueryCounter(id
, target
);
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
2736 void fDeleteQueries(GLsizei n
, const GLuint
* names
) {
2738 ASSERT_SYMBOL_PRESENT(fDeleteQueries
);
2739 mSymbols
.fDeleteQueries(n
, names
);
2741 TRACKING_CONTEXT(DeletedQueries(this, n
, names
));
2744 void fGenQueries(GLsizei n
, GLuint
* names
) {
2746 ASSERT_SYMBOL_PRESENT(fGenQueries
);
2747 mSymbols
.fGenQueries(n
, names
);
2749 TRACKING_CONTEXT(CreatedQueries(this, n
, names
));
2752 void fGetQueryiv(GLenum target
, GLenum pname
, GLint
* params
) {
2754 ASSERT_SYMBOL_PRESENT(fGetQueryiv
);
2755 mSymbols
.fGetQueryiv(target
, pname
, params
);
2760 void fGetQueryObjectuiv(GLuint id
, GLenum pname
, GLuint
* params
) {
2762 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv
);
2763 mSymbols
.fGetQueryObjectuiv(id
, pname
, params
);
2768 realGLboolean
fIsQuery(GLuint query
) {
2769 realGLboolean retval
= false;
2771 ASSERT_SYMBOL_PRESENT(fIsQuery
);
2772 retval
= mSymbols
.fIsQuery(query
);
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
2786 void fGetQueryObjecti64v(GLuint id
, GLenum pname
, GLint64
* params
) {
2788 ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v
);
2789 mSymbols
.fGetQueryObjecti64v(id
, pname
, params
);
2794 void fGetQueryObjectui64v(GLuint id
, GLenum pname
, GLuint64
* params
) {
2796 ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v
);
2797 mSymbols
.fGetQueryObjectui64v(id
, pname
, params
);
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
2814 void fGetQueryObjectiv(GLuint id
, GLenum pname
, GLint
* params
) {
2816 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv
);
2817 mSymbols
.fGetQueryObjectiv(id
, pname
, params
);
2822 // -----------------------------------------------------------------------------
2823 // GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
2825 void fBindBufferBase(GLenum target
, GLuint index
, GLuint buffer
) {
2827 ASSERT_SYMBOL_PRESENT(fBindBufferBase
);
2828 mSymbols
.fBindBufferBase(target
, index
, buffer
);
2832 void fBindBufferRange(GLenum target
, GLuint index
, GLuint buffer
,
2833 GLintptr offset
, GLsizeiptr size
) {
2835 ASSERT_SYMBOL_PRESENT(fBindBufferRange
);
2836 mSymbols
.fBindBufferRange(target
, index
, buffer
, offset
, size
);
2840 void fGenTransformFeedbacks(GLsizei n
, GLuint
* ids
) {
2842 ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks
);
2843 mSymbols
.fGenTransformFeedbacks(n
, ids
);
2848 void fDeleteTransformFeedbacks(GLsizei n
, const GLuint
* ids
) {
2850 ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks
);
2851 mSymbols
.fDeleteTransformFeedbacks(n
, ids
);
2855 realGLboolean
fIsTransformFeedback(GLuint id
) {
2856 realGLboolean result
= false;
2858 ASSERT_SYMBOL_PRESENT(fIsTransformFeedback
);
2859 result
= mSymbols
.fIsTransformFeedback(id
);
2865 void fBindTransformFeedback(GLenum target
, GLuint id
) {
2867 ASSERT_SYMBOL_PRESENT(fBindTransformFeedback
);
2868 mSymbols
.fBindTransformFeedback(target
, id
);
2872 void fBeginTransformFeedback(GLenum primitiveMode
) {
2874 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback
);
2875 mSymbols
.fBeginTransformFeedback(primitiveMode
);
2879 void fEndTransformFeedback() {
2881 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback
);
2882 mSymbols
.fEndTransformFeedback();
2886 void fTransformFeedbackVaryings(GLuint program
, GLsizei count
,
2887 const GLchar
* const* varyings
,
2888 GLenum bufferMode
) {
2890 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings
);
2891 mSymbols
.fTransformFeedbackVaryings(program
, count
, varyings
, bufferMode
);
2895 void fGetTransformFeedbackVarying(GLuint program
, GLuint index
,
2896 GLsizei bufSize
, GLsizei
* length
,
2897 GLsizei
* size
, GLenum
* type
, GLchar
* name
) {
2899 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying
);
2900 mSymbols
.fGetTransformFeedbackVarying(program
, index
, bufSize
, length
, size
,
2906 void fPauseTransformFeedback() {
2908 ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback
);
2909 mSymbols
.fPauseTransformFeedback();
2913 void fResumeTransformFeedback() {
2915 ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback
);
2916 mSymbols
.fResumeTransformFeedback();
2920 void fGetIntegeri_v(GLenum param
, GLuint index
, GLint
* values
) {
2922 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v
);
2923 mSymbols
.fGetIntegeri_v(param
, index
, values
);
2928 void fGetInteger64i_v(GLenum target
, GLuint index
, GLint64
* data
) {
2929 ASSERT_SYMBOL_PRESENT(fGetInteger64i_v
);
2931 mSymbols
.fGetInteger64i_v(target
, index
, data
);
2936 // -----------------------------------------------------------------------------
2937 // Package XXX_vertex_array_object
2939 void fBindVertexArray(GLuint array
) {
2941 ASSERT_SYMBOL_PRESENT(fBindVertexArray
);
2942 mSymbols
.fBindVertexArray(array
);
2946 void fDeleteVertexArrays(GLsizei n
, const GLuint
* arrays
) {
2948 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays
);
2949 mSymbols
.fDeleteVertexArrays(n
, arrays
);
2953 void fGenVertexArrays(GLsizei n
, GLuint
* arrays
) {
2955 ASSERT_SYMBOL_PRESENT(fGenVertexArrays
);
2956 mSymbols
.fGenVertexArrays(n
, arrays
);
2960 realGLboolean
fIsVertexArray(GLuint array
) {
2961 realGLboolean ret
= false;
2963 ASSERT_SYMBOL_PRESENT(fIsVertexArray
);
2964 ret
= mSymbols
.fIsVertexArray(array
);
2970 // -----------------------------------------------------------------------------
2971 // Extension NV_fence
2973 void fGenFences(GLsizei n
, GLuint
* fences
) {
2974 ASSERT_SYMBOL_PRESENT(fGenFences
);
2976 mSymbols
.fGenFences(n
, fences
);
2980 void fDeleteFences(GLsizei n
, const GLuint
* fences
) {
2981 ASSERT_SYMBOL_PRESENT(fDeleteFences
);
2983 mSymbols
.fDeleteFences(n
, fences
);
2987 void fSetFence(GLuint fence
, GLenum condition
) {
2988 ASSERT_SYMBOL_PRESENT(fSetFence
);
2990 mSymbols
.fSetFence(fence
, condition
);
2994 realGLboolean
fTestFence(GLuint fence
) {
2995 realGLboolean ret
= false;
2996 ASSERT_SYMBOL_PRESENT(fTestFence
);
2998 ret
= mSymbols
.fTestFence(fence
);
3004 void fFinishFence(GLuint fence
) {
3005 ASSERT_SYMBOL_PRESENT(fFinishFence
);
3007 mSymbols
.fFinishFence(fence
);
3012 realGLboolean
fIsFence(GLuint fence
) {
3013 realGLboolean ret
= false;
3014 ASSERT_SYMBOL_PRESENT(fIsFence
);
3016 ret
= mSymbols
.fIsFence(fence
);
3022 void fGetFenceiv(GLuint fence
, GLenum pname
, GLint
* params
) {
3023 ASSERT_SYMBOL_PRESENT(fGetFenceiv
);
3025 mSymbols
.fGetFenceiv(fence
, pname
, params
);
3030 // -----------------------------------------------------------------------------
3031 // Extension NV_texture_barrier
3033 void fTextureBarrier() {
3034 ASSERT_SYMBOL_PRESENT(fTextureBarrier
);
3036 mSymbols
.fTextureBarrier();
3040 // Core GL & Extension ARB_copy_buffer
3042 void fCopyBufferSubData(GLenum readtarget
, GLenum writetarget
,
3043 GLintptr readoffset
, GLintptr writeoffset
,
3046 ASSERT_SYMBOL_PRESENT(fCopyBufferSubData
);
3047 mSymbols
.fCopyBufferSubData(readtarget
, writetarget
, readoffset
,
3052 // -----------------------------------------------------------------------------
3053 // Core GL & Extension ARB_map_buffer_range
3055 void* fMapBufferRange(GLenum target
, GLintptr offset
, GLsizeiptr length
,
3056 GLbitfield access
) {
3057 void* data
= nullptr;
3058 ASSERT_SYMBOL_PRESENT(fMapBufferRange
);
3060 data
= mSymbols
.fMapBufferRange(target
, offset
, length
, access
);
3066 void fFlushMappedBufferRange(GLenum target
, GLintptr offset
,
3067 GLsizeiptr length
) {
3068 ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange
);
3070 mSymbols
.fFlushMappedBufferRange(target
, offset
, length
);
3074 // -----------------------------------------------------------------------------
3075 // Core GL & Extension ARB_sampler_objects
3077 void fGenSamplers(GLsizei count
, GLuint
* samplers
) {
3079 ASSERT_SYMBOL_PRESENT(fGenSamplers
);
3080 mSymbols
.fGenSamplers(count
, samplers
);
3084 void fDeleteSamplers(GLsizei count
, const GLuint
* samplers
) {
3086 ASSERT_SYMBOL_PRESENT(fDeleteSamplers
);
3087 mSymbols
.fDeleteSamplers(count
, samplers
);
3091 realGLboolean
fIsSampler(GLuint sampler
) {
3092 realGLboolean result
= false;
3094 ASSERT_SYMBOL_PRESENT(fIsSampler
);
3095 result
= mSymbols
.fIsSampler(sampler
);
3101 void fBindSampler(GLuint unit
, GLuint sampler
) {
3103 ASSERT_SYMBOL_PRESENT(fBindSampler
);
3104 mSymbols
.fBindSampler(unit
, sampler
);
3108 void fSamplerParameteri(GLuint sampler
, GLenum pname
, GLint param
) {
3110 ASSERT_SYMBOL_PRESENT(fSamplerParameteri
);
3111 mSymbols
.fSamplerParameteri(sampler
, pname
, param
);
3115 void fSamplerParameteriv(GLuint sampler
, GLenum pname
, const GLint
* param
) {
3117 ASSERT_SYMBOL_PRESENT(fSamplerParameteriv
);
3118 mSymbols
.fSamplerParameteriv(sampler
, pname
, param
);
3122 void fSamplerParameterf(GLuint sampler
, GLenum pname
, GLfloat param
) {
3124 ASSERT_SYMBOL_PRESENT(fSamplerParameterf
);
3125 mSymbols
.fSamplerParameterf(sampler
, pname
, param
);
3129 void fSamplerParameterfv(GLuint sampler
, GLenum pname
, const GLfloat
* param
) {
3131 ASSERT_SYMBOL_PRESENT(fSamplerParameterfv
);
3132 mSymbols
.fSamplerParameterfv(sampler
, pname
, param
);
3136 void fGetSamplerParameteriv(GLuint sampler
, GLenum pname
, GLint
* params
) {
3138 ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv
);
3139 mSymbols
.fGetSamplerParameteriv(sampler
, pname
, params
);
3143 void fGetSamplerParameterfv(GLuint sampler
, GLenum pname
, GLfloat
* params
) {
3145 ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv
);
3146 mSymbols
.fGetSamplerParameterfv(sampler
, pname
, params
);
3150 // -----------------------------------------------------------------------------
3151 // Core GL & Extension ARB_uniform_buffer_object
3153 void fGetUniformIndices(GLuint program
, GLsizei uniformCount
,
3154 const GLchar
* const* uniformNames
,
3155 GLuint
* uniformIndices
) {
3156 ASSERT_SYMBOL_PRESENT(fGetUniformIndices
);
3158 mSymbols
.fGetUniformIndices(program
, uniformCount
, uniformNames
,
3164 void fGetActiveUniformsiv(GLuint program
, GLsizei uniformCount
,
3165 const GLuint
* uniformIndices
, GLenum pname
,
3167 ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv
);
3169 mSymbols
.fGetActiveUniformsiv(program
, uniformCount
, uniformIndices
, pname
,
3175 GLuint
fGetUniformBlockIndex(GLuint program
, const GLchar
* uniformBlockName
) {
3177 ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex
);
3179 result
= mSymbols
.fGetUniformBlockIndex(program
, uniformBlockName
);
3185 void fGetActiveUniformBlockiv(GLuint program
, GLuint uniformBlockIndex
,
3186 GLenum pname
, GLint
* params
) {
3187 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv
);
3189 mSymbols
.fGetActiveUniformBlockiv(program
, uniformBlockIndex
, pname
,
3195 void fGetActiveUniformBlockName(GLuint program
, GLuint uniformBlockIndex
,
3196 GLsizei bufSize
, GLsizei
* length
,
3197 GLchar
* uniformBlockName
) {
3198 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName
);
3200 mSymbols
.fGetActiveUniformBlockName(program
, uniformBlockIndex
, bufSize
,
3201 length
, uniformBlockName
);
3206 void fUniformBlockBinding(GLuint program
, GLuint uniformBlockIndex
,
3207 GLuint uniformBlockBinding
) {
3208 ASSERT_SYMBOL_PRESENT(fUniformBlockBinding
);
3210 mSymbols
.fUniformBlockBinding(program
, uniformBlockIndex
,
3211 uniformBlockBinding
);
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
) {
3220 ASSERT_SYMBOL_PRESENT(fTexStorage2D
);
3221 mSymbols
.fTexStorage2D(target
, levels
, internalformat
, width
, height
);
3226 void fTexStorage3D(GLenum target
, GLsizei levels
, GLenum internalformat
,
3227 GLsizei width
, GLsizei height
, GLsizei depth
) {
3229 ASSERT_SYMBOL_PRESENT(fTexStorage3D
);
3230 mSymbols
.fTexStorage3D(target
, levels
, internalformat
, width
, height
,
3236 // -----------------------------------------------------------------------------
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
) {
3242 ASSERT_SYMBOL_PRESENT(fTexImage3D
);
3243 mSymbols
.fTexImage3D(target
, level
, internalFormat
, width
, height
, depth
,
3244 border
, format
, type
, data
);
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
) {
3254 ASSERT_SYMBOL_PRESENT(fTexSubImage3D
);
3255 mSymbols
.fTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
, width
,
3256 height
, depth
, format
, type
, pixels
);
3261 void fCopyTexSubImage3D(GLenum target
, GLint level
, GLint xoffset
,
3262 GLint yoffset
, GLint zoffset
, GLint x
, GLint y
,
3263 GLsizei width
, GLsizei height
) {
3266 ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D
);
3267 mSymbols
.fCopyTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
, x
, y
,
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
) {
3278 ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D
);
3279 mSymbols
.fCompressedTexImage3D(target
, level
, internalformat
, width
, height
,
3280 depth
, border
, imageSize
, data
);
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
) {
3289 ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D
);
3290 mSymbols
.fCompressedTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
3291 width
, height
, depth
, format
, imageSize
,
3296 // -----------------------------------------------------------------------------
3299 const GLubyte
* fGetStringi(GLenum name
, GLuint index
) {
3300 const GLubyte
* ret
= nullptr;
3302 ASSERT_SYMBOL_PRESENT(fGetStringi
);
3303 ret
= mSymbols
.fGetStringi(name
, index
);
3309 // -----------------------------------------------------------------------------
3310 // APPLE_framebuffer_multisample
3312 void fResolveMultisampleFramebufferAPPLE() {
3314 ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE
);
3315 mSymbols
.fResolveMultisampleFramebufferAPPLE();
3319 // -----------------------------------------------------------------------------
3322 void fFinishObjectAPPLE(GLenum object
, GLint name
) {
3324 ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE
);
3325 mSymbols
.fFinishObjectAPPLE(object
, name
);
3329 realGLboolean
fTestObjectAPPLE(GLenum object
, GLint name
) {
3330 realGLboolean ret
= false;
3332 ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE
);
3333 ret
= mSymbols
.fTestObjectAPPLE(object
, name
);
3338 // -----------------------------------------------------------------------------
3341 void fPrimitiveRestartIndex(GLuint index
) {
3343 ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex
);
3344 mSymbols
.fPrimitiveRestartIndex(index
);
3348 // -----------------------------------------------------------------------------
3351 void fFramebufferTextureMultiview(GLenum target
, GLenum attachment
,
3352 GLuint texture
, GLint level
,
3353 GLint baseViewIndex
,
3354 GLsizei numViews
) const {
3356 ASSERT_SYMBOL_PRESENT(fFramebufferTextureMultiview
);
3357 mSymbols
.fFramebufferTextureMultiview(target
, attachment
, texture
, level
,
3358 baseViewIndex
, numViews
);
3363 // draw_buffers_indexed
3365 void fBlendEquationSeparatei(GLuint i
, GLenum modeRGB
,
3366 GLenum modeAlpha
) const {
3368 mSymbols
.fBlendEquationSeparatei(i
, modeRGB
, modeAlpha
);
3372 void fBlendFuncSeparatei(GLuint i
, GLenum sfactorRGB
, GLenum dfactorRGB
,
3373 GLenum sfactorAlpha
, GLenum dfactorAlpha
) const {
3375 mSymbols
.fBlendFuncSeparatei(i
, sfactorRGB
, dfactorRGB
, sfactorAlpha
,
3380 void fColorMaski(GLuint i
, realGLboolean red
, realGLboolean green
,
3381 realGLboolean blue
, realGLboolean alpha
) const {
3383 mSymbols
.fColorMaski(i
, red
, green
, blue
, alpha
);
3387 void fDisablei(GLenum capability
, GLuint i
) const {
3389 mSymbols
.fDisablei(capability
, i
);
3393 void fEnablei(GLenum capability
, GLuint i
) const {
3395 mSymbols
.fEnablei(capability
, i
);
3401 void fProvokingVertex(GLenum mode
) const {
3403 mSymbols
.fProvokingVertex(mode
);
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 // -----------------------------------------------------------------------------
3418 explicit GLContext(const GLContextDesc
&, GLContext
* sharedContext
= nullptr,
3419 bool canUseTLSIsCurrent
= false);
3421 // -----------------------------------------------------------------------------
3424 virtual ~GLContext();
3426 // Mark this context as destroyed. This will nullptr out all
3427 // the GL function pointers!
3428 void MarkDestroyed();
3431 virtual void OnMarkDestroyed() {}
3433 // -----------------------------------------------------------------------------
3434 // Everything that isn't standard GL APIs
3436 typedef gfx::SurfaceFormat SurfaceFormat
;
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();
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());
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
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
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
;
3553 return IsExtensionSupported(OES_EGL_image_external
)
3554 ? LOCAL_GL_TEXTURE_EXTERNAL
3555 : LOCAL_GL_TEXTURE_2D
;
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
);
3567 DebugFlagEnabled
= 1 << 0,
3568 DebugFlagTrace
= 1 << 1,
3569 DebugFlagAbortOnError
= 1 << 2
3572 const uint8_t mDebugFlags
;
3573 static uint8_t ChooseDebugFlags(CreateContextFlags createFlags
);
3576 RefPtr
<GLContext
> mSharedContext
;
3579 // The thread id which this context was created.
3580 Maybe
<PlatformThreadId
> mOwningThreadId
;
3583 GLContextSymbols mSymbols
= {};
3585 UniquePtr
<GLBlitHelper
> mBlitHelper
;
3586 UniquePtr
<GLReadTexImageHelper
> mReadTexImageHelper
;
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
);
3621 SharedSurface
* mLockedSurface
= nullptr;
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();
3643 void LoadMoreSymbols(const SymbolLoader
& loader
);
3644 bool LoadExtSymbols(const SymbolLoader
& loader
, const SymLoadStruct
* list
,
3646 bool LoadFeatureSymbols(const SymbolLoader
& loader
, const SymLoadStruct
* list
,
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
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
3681 return width
<= maxSize
&& height
<= maxSize
;
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) {}
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;
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
;
3746 bool mHeavyGLCallsSinceLastFlush
= false;
3749 void FlushIfHeavyGLCallsSinceLastFlush();
3750 static bool ShouldSpew();
3751 static bool ShouldDumpExts();
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
);
3764 GLuint
CreateFramebuffer() {
3766 fGenFramebuffers(1, &x
);
3769 GLuint
CreateRenderbuffer() {
3771 fGenRenderbuffers(1, &x
);
3774 GLuint
CreateTexture() {
3776 fGenTextures(1, &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
);
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;
3804 void MarkBitfieldByStrings(const std::vector
<nsCString
>& strList
,
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
);
3812 printf_stderr(" %s%s\n", str
.BeginReading(), wasMarked
? "(*)" : "");
3818 class Renderbuffer final
{
3820 const WeakPtr
<GLContext
> weakGl
;
3824 static GLuint
Create(GLContext
& gl
) {
3826 gl
.fGenRenderbuffers(1, &ret
);
3831 explicit Renderbuffer(GLContext
& gl
) : weakGl(&gl
), name(Create(gl
)) {}
3834 const RefPtr
<GLContext
> gl
= weakGl
.get();
3835 if (!gl
|| !gl
->MakeCurrent()) return;
3836 gl
->fDeleteRenderbuffers(1, &name
);
3842 class Texture final
{
3844 const WeakPtr
<GLContext
> weakGl
;
3848 static GLuint
Create(GLContext
& gl
) {
3850 gl
.fGenTextures(1, &ret
);
3855 explicit Texture(GLContext
& gl
) : weakGl(&gl
), name(Create(gl
)) {}
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_ */