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"
41 #include "nsRegionFwd.h"
43 #include "GLContextTypes.h"
44 #include "GLContextSymbols.h"
45 #include "base/platform_thread.h" // for PlatformThreadId
46 #include "mozilla/GenericRefCounted.h"
47 #include "mozilla/WeakPtr.h"
49 #ifdef MOZ_WIDGET_ANDROID
50 # include "mozilla/ProfilerLabels.h"
58 class GLReadTexImageHelper
;
65 class ColorTextureLayerProgram
;
69 class CompositorWidget
;
71 } // namespace mozilla
76 enum class GLFeature
{
88 EXT_color_buffer_float
,
92 framebuffer_multisample
,
94 framebuffer_object_EXT_OES
,
96 get_integer64_indexed
,
97 get_query_object_i64v
,
101 instanced_non_arrays
,
102 internalformat_query
,
103 invalidate_framebuffer
,
107 occlusion_query_boolean
,
109 packed_depth_stencil
,
117 renderbuffer_color_float
,
118 renderbuffer_color_half_float
,
119 robust_buffer_access_behavior
,
123 seamless_cube_map_opt_in
,
126 standard_derivatives
,
129 texture_3D_compressed
,
131 texture_compression_bptc
,
132 texture_compression_rgtc
,
134 texture_float_linear
,
136 texture_half_float_linear
,
137 texture_non_power_of_two
,
143 uniform_buffer_object
,
144 uniform_matrix_nonsquare
,
149 enum class ContextProfile
: uint8_t {
156 enum class GLRenderer
{
175 MicrosoftBasicRenderDriver
,
179 class GLContext
: public GenericAtomicRefCounted
, public SupportsWeakPtr
{
181 static MOZ_THREAD_LOCAL(const GLContext
*) sCurrentContext
;
183 const GLContextDesc mDesc
;
185 bool mImplicitMakeCurrent
= false;
186 bool mUseTLSIsCurrent
;
188 class TlsScope final
{
189 const WeakPtr
<GLContext
> mGL
;
190 const bool mWasTlsOk
;
193 explicit TlsScope(GLContext
* const gl
)
194 : mGL(gl
), mWasTlsOk(gl
&& gl
->mUseTLSIsCurrent
) {
196 mGL
->mUseTLSIsCurrent
= true;
202 mGL
->mUseTLSIsCurrent
= mWasTlsOk
;
207 // -----------------------------------------------------------------------------
211 * Returns true if the context is using ANGLE. This should only be overridden
212 * for an ANGLE implementation.
214 virtual bool IsANGLE() const { return false; }
217 * Returns true if the context is using WARP. This should only be overridden
218 * for an ANGLE implementation.
220 virtual bool IsWARP() const { return false; }
222 virtual void GetWSIInfo(nsCString
* const out
) const = 0;
225 * Return true if we are running on a OpenGL core profile context
227 inline bool IsCoreProfile() const {
228 MOZ_ASSERT(mProfile
!= ContextProfile::Unknown
, "unknown context profile");
230 return mProfile
== ContextProfile::OpenGLCore
;
234 * Return true if we are running on a OpenGL compatibility profile context
235 * (legacy profile 2.1 on Max OS X)
237 inline bool IsCompatibilityProfile() const {
238 MOZ_ASSERT(mProfile
!= ContextProfile::Unknown
, "unknown context profile");
240 return mProfile
== ContextProfile::OpenGLCompatibility
;
243 inline bool IsGLES() const {
244 MOZ_ASSERT(mProfile
!= ContextProfile::Unknown
, "unknown context profile");
246 return mProfile
== ContextProfile::OpenGLES
;
249 inline bool IsAtLeast(ContextProfile profile
, unsigned int version
) const {
250 MOZ_ASSERT(profile
!= ContextProfile::Unknown
,
251 "IsAtLeast: bad <profile> parameter");
252 MOZ_ASSERT(mProfile
!= ContextProfile::Unknown
, "unknown context profile");
253 MOZ_ASSERT(mVersion
!= 0, "unknown context version");
255 if (version
> mVersion
) {
259 return profile
== mProfile
;
263 * Return the version of the context.
265 * If this a OpenGL 2.1, that will return 210
267 inline uint32_t Version() const { return mVersion
; }
269 inline uint32_t ShadingLanguageVersion() const {
270 return mShadingLanguageVersion
;
273 GLVendor
Vendor() const { return mVendor
; }
274 GLRenderer
Renderer() const { return mRenderer
; }
275 bool IsMesa() const { return mIsMesa
; }
277 bool IsContextLost() const { return mContextLost
; }
279 bool CheckContextLost() const {
280 mTopError
= GetError();
281 return IsContextLost();
284 bool HasPBOState() const { return (!IsGLES() || Version() >= 300); }
287 * If this context is double-buffered, returns TRUE.
289 virtual bool IsDoubleBuffered() const { return false; }
291 virtual GLContextType
GetContextType() const = 0;
293 virtual bool IsCurrentImpl() const = 0;
294 virtual bool MakeCurrentImpl() const = 0;
296 bool IsCurrent() const {
297 if (mImplicitMakeCurrent
) return MakeCurrent();
299 return IsCurrentImpl();
302 bool MakeCurrent(bool aForce
= false) const;
305 * Get the default framebuffer for this context.
307 UniquePtr
<MozFramebuffer
> mOffscreenDefaultFb
;
309 bool CreateOffscreenDefaultFb(const gfx::IntSize
& size
);
311 virtual GLuint
GetDefaultFramebuffer() {
312 if (mOffscreenDefaultFb
) {
313 return mOffscreenDefaultFb
->mFB
;
319 * mVersion store the OpenGL's version, multiplied by 100. For example, if
320 * the context is an OpenGL 2.1 context, mVersion value will be 210.
322 uint32_t mVersion
= 0;
323 ContextProfile mProfile
= ContextProfile::Unknown
;
325 uint32_t mShadingLanguageVersion
= 0;
327 GLVendor mVendor
= GLVendor::Other
;
328 GLRenderer mRenderer
= GLRenderer::Other
;
329 bool mIsMesa
= false;
331 // -----------------------------------------------------------------------------
332 // Extensions management
334 * This mechanism is designed to know if an extension is supported. In the
335 * long term, we would like to only use the extension group queries XXX_* to
336 * have full compatibility with context version and profiles (especialy the
337 * core that officialy don't bring any extensions).
341 * Known GL extensions that can be queried by
342 * IsExtensionSupported. The results of this are cached, and as
343 * such it's safe to use this even in performance critical code.
344 * If you add to this array, remember to add to the string names
349 AMD_compressed_ATC_texture
,
351 ANGLE_framebuffer_blit
,
352 ANGLE_framebuffer_multisample
,
353 ANGLE_instanced_arrays
,
355 ANGLE_provoking_vertex
,
356 ANGLE_texture_compression_dxt3
,
357 ANGLE_texture_compression_dxt5
,
359 APPLE_client_storage
,
361 APPLE_framebuffer_multisample
,
364 APPLE_vertex_array_object
,
365 ARB_ES2_compatibility
,
366 ARB_ES3_compatibility
,
367 ARB_color_buffer_float
,
373 ARB_framebuffer_object
,
374 ARB_framebuffer_sRGB
,
375 ARB_geometry_shader4
,
376 ARB_half_float_pixel
,
377 ARB_instanced_arrays
,
378 ARB_internalformat_query
,
379 ARB_invalidate_subdata
,
380 ARB_map_buffer_range
,
381 ARB_occlusion_query2
,
382 ARB_pixel_buffer_object
,
383 ARB_provoking_vertex
,
384 ARB_robust_buffer_access_behavior
,
387 ARB_seamless_cube_map
,
388 ARB_shader_texture_lod
,
390 ARB_texture_compression
,
391 ARB_texture_compression_bptc
,
392 ARB_texture_compression_rgtc
,
394 ARB_texture_non_power_of_two
,
395 ARB_texture_rectangle
,
400 ARB_transform_feedback2
,
401 ARB_uniform_buffer_object
,
402 ARB_vertex_array_object
,
403 CHROMIUM_color_buffer_float_rgb
,
404 CHROMIUM_color_buffer_float_rgba
,
407 EXT_color_buffer_float
,
408 EXT_color_buffer_half_float
,
410 EXT_disjoint_timer_query
,
416 EXT_framebuffer_blit
,
417 EXT_framebuffer_multisample
,
418 EXT_framebuffer_object
,
419 EXT_framebuffer_sRGB
,
421 EXT_map_buffer_range
,
422 EXT_multisampled_render_to_texture
,
423 EXT_occlusion_query_boolean
,
424 EXT_packed_depth_stencil
,
425 EXT_provoking_vertex
,
426 EXT_read_format_bgra
,
429 EXT_sRGB_write_control
,
430 EXT_shader_texture_lod
,
431 EXT_texture_compression_bptc
,
432 EXT_texture_compression_dxt1
,
433 EXT_texture_compression_rgtc
,
434 EXT_texture_compression_s3tc
,
435 EXT_texture_compression_s3tc_srgb
,
436 EXT_texture_filter_anisotropic
,
437 EXT_texture_format_BGRA8888
,
442 EXT_transform_feedback
,
445 IMG_texture_compression_pvrtc
,
448 KHR_parallel_shader_compile
,
449 KHR_robust_buffer_access_behavior
,
451 KHR_texture_compression_astc_hdr
,
452 KHR_texture_compression_astc_ldr
,
456 NV_geometry_program4
,
459 NV_primitive_restart
,
461 NV_transform_feedback
,
462 NV_transform_feedback2
,
464 OES_EGL_image_external
,
466 OES_compressed_ETC1_RGB8_texture
,
470 OES_draw_buffers_indexed
,
471 OES_element_index_uint
,
472 OES_fbo_render_mipmap
,
473 OES_framebuffer_object
,
474 OES_packed_depth_stencil
,
476 OES_standard_derivatives
,
480 OES_texture_float_linear
,
481 OES_texture_half_float
,
482 OES_texture_half_float_linear
,
484 OES_vertex_array_object
,
490 bool IsExtensionSupported(GLExtensions aKnownExtension
) const {
491 return mAvailableExtensions
[aKnownExtension
];
495 void MarkExtensionUnsupported(GLExtensions aKnownExtension
) {
496 mAvailableExtensions
[aKnownExtension
] = 0;
499 void MarkExtensionSupported(GLExtensions aKnownExtension
) {
500 mAvailableExtensions
[aKnownExtension
] = 1;
503 std::bitset
<Extensions_Max
> mAvailableExtensions
;
505 // -----------------------------------------------------------------------------
508 * This mecahnism introduces a new way to check if a OpenGL feature is
509 * supported, regardless of whether it is supported by an extension or
510 * natively by the context version/profile
513 bool IsSupported(GLFeature feature
) const {
514 return mAvailableFeatures
[size_t(feature
)];
517 static const char* GetFeatureName(GLFeature feature
);
520 std::bitset
<size_t(GLFeature::EnumMax
)> mAvailableFeatures
;
523 * Init features regarding OpenGL extension and context version and profile
528 * Mark the feature and associated extensions as unsupported
530 void MarkUnsupported(GLFeature feature
);
533 * Is this feature supported using the core (unsuffixed) symbols?
535 bool IsFeatureProvidedByCoreSymbols(GLFeature feature
);
537 // -----------------------------------------------------------------------------
541 mutable bool mContextLost
= false;
542 mutable GLenum mTopError
= 0;
545 void OnContextLostError() const;
548 static std::string
GLErrorToString(GLenum aError
);
550 static bool IsBadCallError(const GLenum err
) {
551 return !(err
== 0 || err
== LOCAL_GL_CONTEXT_LOST
);
554 class LocalErrorScope
;
557 mutable std::stack
<const LocalErrorScope
*> mLocalErrorScopeStack
;
558 mutable UniquePtr
<LocalErrorScope
> mDebugErrorScope
;
560 ////////////////////////////////////
561 // Use this safer option.
564 class LocalErrorScope
{
565 const GLContext
& mGL
;
567 bool mHasBeenChecked
;
570 explicit LocalErrorScope(const GLContext
& gl
)
571 : mGL(gl
), mHasBeenChecked(false) {
572 mGL
.mLocalErrorScopeStack
.push(this);
573 mOldTop
= mGL
.GetError();
576 /// Never returns CONTEXT_LOST.
578 MOZ_ASSERT(!mHasBeenChecked
);
579 mHasBeenChecked
= true;
581 const auto ret
= mGL
.GetError();
582 if (ret
== LOCAL_GL_CONTEXT_LOST
) return 0;
587 MOZ_ASSERT(mHasBeenChecked
);
589 MOZ_ASSERT(!IsBadCallError(mGL
.GetError()));
591 MOZ_ASSERT(mGL
.mLocalErrorScopeStack
.top() == this);
592 mGL
.mLocalErrorScopeStack
.pop();
594 mGL
.mTopError
= mOldTop
;
600 bool GetPotentialInteger(GLenum pname
, GLint
* param
) {
601 LocalErrorScope
localError(*this);
603 fGetIntegerv(pname
, param
);
605 GLenum err
= localError
.GetError();
606 MOZ_ASSERT_IF(err
!= LOCAL_GL_NO_ERROR
, err
== LOCAL_GL_INVALID_ENUM
);
607 return err
== LOCAL_GL_NO_ERROR
;
610 void DebugCallback(GLenum source
, GLenum type
, GLuint id
, GLenum severity
,
611 GLsizei length
, const GLchar
* message
);
614 static void GLAPIENTRY
StaticDebugCallback(GLenum source
, GLenum type
,
615 GLuint id
, GLenum severity
,
617 const GLchar
* message
,
618 const GLvoid
* userParam
);
620 // -----------------------------------------------------------------------------
621 // Debugging implementation
623 #ifndef MOZ_FUNCTION_NAME
625 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
626 # elif defined(_MSC_VER)
627 # define MOZ_FUNCTION_NAME __FUNCTION__
629 # define MOZ_FUNCTION_NAME \
630 __func__ // defined in C99, supported in various C++ compilers. Just raw
635 #ifdef MOZ_WIDGET_ANDROID
636 // Record the name of the GL call for better hang stacks on Android.
637 # define ANDROID_ONLY_PROFILER_LABEL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
639 # define ANDROID_ONLY_PROFILER_LABEL
642 #define BEFORE_GL_CALL \
643 ANDROID_ONLY_PROFILER_LABEL \
644 if (MOZ_LIKELY(BeforeGLCall(MOZ_FUNCTION_NAME))) { \
648 #define AFTER_GL_CALL \
649 AfterGLCall(MOZ_FUNCTION_NAME); \
654 void BeforeGLCall_Debug(const char* funcName
) const;
655 void AfterGLCall_Debug(const char* funcName
) const;
656 static void OnImplicitMakeCurrentFailure(const char* funcName
);
658 bool BeforeGLCall(const char* const funcName
) const {
659 if (mImplicitMakeCurrent
) {
660 if (MOZ_UNLIKELY(!MakeCurrent())) {
662 OnImplicitMakeCurrentFailure(funcName
);
667 MOZ_GL_ASSERT(this, IsCurrentImpl());
669 if (MOZ_UNLIKELY(mDebugFlags
)) {
670 BeforeGLCall_Debug(funcName
);
675 void AfterGLCall(const char* const funcName
) const {
676 if (MOZ_UNLIKELY(mDebugFlags
)) {
677 AfterGLCall_Debug(funcName
);
681 GLContext
* TrackingContext() {
682 GLContext
* tip
= this;
683 while (tip
->mSharedContext
) tip
= tip
->mSharedContext
;
687 static void AssertNotPassingStackBufferToTheGL(const void* ptr
);
689 #ifdef MOZ_GL_DEBUG_BUILD
691 # define TRACKING_CONTEXT(a) \
693 TrackingContext()->a; \
696 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
697 AssertNotPassingStackBufferToTheGL(ptr)
699 # define ASSERT_SYMBOL_PRESENT(func) \
701 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, \
702 "Mismatched symbol check."); \
703 if (MOZ_UNLIKELY(!mSymbols.func)) { \
704 printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", \
706 MOZ_CRASH("GFX: Uninitialized GL function"); \
710 #else // ifdef MOZ_GL_DEBUG_BUILD
712 # define TRACKING_CONTEXT(a) \
715 # define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) \
718 # define ASSERT_SYMBOL_PRESENT(func) \
722 #endif // ifdef MOZ_GL_DEBUG_BUILD
724 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
726 void BeforeGLDrawCall() {}
728 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
730 void AfterGLDrawCall() { mHeavyGLCallsSinceLastFlush
= true; }
732 // Do whatever setup is necessary to read from our offscreen FBO, if it's
734 void BeforeGLReadCall() {}
736 // Do whatever tear-down is necessary after reading from our offscreen FBO,
738 void AfterGLReadCall() {}
741 void OnSyncCall() const { mSyncGLCallCount
++; }
743 uint64_t GetSyncCallCount() const { return mSyncGLCallCount
; }
745 void ResetSyncCallCount(const char* resetReason
) const;
747 // -----------------------------------------------------------------------------
748 // GL official entry points
750 // We smash all errors together, so you never have to loop on this. We
751 // guarantee that immediately after this call, there are no errors left.
752 // Always returns the top-most error, except if followed by CONTEXT_LOST, then
753 // return that instead.
754 GLenum
GetError() const;
756 GLenum
fGetError() { return GetError(); }
758 GLenum
fGetGraphicsResetStatus() const;
762 void fActiveTexture(GLenum texture
) {
764 mSymbols
.fActiveTexture(texture
);
768 void fAttachShader(GLuint program
, GLuint shader
) {
770 mSymbols
.fAttachShader(program
, shader
);
774 void fBeginQuery(GLenum target
, GLuint id
) {
776 ASSERT_SYMBOL_PRESENT(fBeginQuery
);
777 mSymbols
.fBeginQuery(target
, id
);
781 void fBindAttribLocation(GLuint program
, GLuint index
, const GLchar
* name
) {
783 mSymbols
.fBindAttribLocation(program
, index
, name
);
787 void fBindBuffer(GLenum target
, GLuint buffer
) {
789 mSymbols
.fBindBuffer(target
, buffer
);
793 void fInvalidateFramebuffer(GLenum target
, GLsizei numAttachments
,
794 const GLenum
* attachments
) {
797 ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer
);
798 mSymbols
.fInvalidateFramebuffer(target
, numAttachments
, attachments
);
803 void fInvalidateSubFramebuffer(GLenum target
, GLsizei numAttachments
,
804 const GLenum
* attachments
, GLint x
, GLint y
,
805 GLsizei width
, GLsizei height
) {
808 ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer
);
809 mSymbols
.fInvalidateSubFramebuffer(target
, numAttachments
, attachments
, x
,
815 void fBindTexture(GLenum target
, GLuint texture
) {
817 mSymbols
.fBindTexture(target
, texture
);
821 void fBlendColor(GLfloat red
, GLfloat green
, GLfloat blue
, GLfloat alpha
) {
823 mSymbols
.fBlendColor(red
, green
, blue
, alpha
);
827 void fBlendEquation(GLenum mode
) {
829 mSymbols
.fBlendEquation(mode
);
833 void fBlendEquationSeparate(GLenum modeRGB
, GLenum modeAlpha
) {
835 mSymbols
.fBlendEquationSeparate(modeRGB
, modeAlpha
);
839 void fBlendFunc(GLenum sfactor
, GLenum dfactor
) {
841 mSymbols
.fBlendFunc(sfactor
, dfactor
);
845 void fBlendFuncSeparate(GLenum sfactorRGB
, GLenum dfactorRGB
,
846 GLenum sfactorAlpha
, GLenum dfactorAlpha
) {
848 mSymbols
.fBlendFuncSeparate(sfactorRGB
, dfactorRGB
, sfactorAlpha
,
854 void raw_fBufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
856 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data
);
858 mSymbols
.fBufferData(target
, size
, data
, usage
);
861 mHeavyGLCallsSinceLastFlush
= true;
865 void fBufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
867 raw_fBufferData(target
, size
, data
, usage
);
870 if (WorkAroundDriverBugs() && !data
&& Vendor() == GLVendor::NVIDIA
) {
871 UniquePtr
<char[]> buf
= MakeUnique
<char[]>(1);
873 fBufferSubData(target
, size
- 1, 1, buf
.get());
877 void fBufferSubData(GLenum target
, GLintptr offset
, GLsizeiptr size
,
878 const GLvoid
* data
) {
879 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data
);
881 mSymbols
.fBufferSubData(target
, offset
, size
, data
);
883 mHeavyGLCallsSinceLastFlush
= true;
887 void raw_fClear(GLbitfield mask
) {
889 mSymbols
.fClear(mask
);
894 void fClear(GLbitfield mask
) {
900 void fClearBufferfi(GLenum buffer
, GLint drawbuffer
, GLfloat depth
,
904 mSymbols
.fClearBufferfi(buffer
, drawbuffer
, depth
, stencil
);
909 void fClearBufferfv(GLenum buffer
, GLint drawbuffer
, const GLfloat
* value
) {
912 mSymbols
.fClearBufferfv(buffer
, drawbuffer
, value
);
917 void fClearBufferiv(GLenum buffer
, GLint drawbuffer
, const GLint
* value
) {
920 mSymbols
.fClearBufferiv(buffer
, drawbuffer
, value
);
925 void fClearBufferuiv(GLenum buffer
, GLint drawbuffer
, const GLuint
* value
) {
928 mSymbols
.fClearBufferuiv(buffer
, drawbuffer
, value
);
933 void fClearColor(GLfloat r
, GLfloat g
, GLfloat b
, GLfloat a
) {
935 mSymbols
.fClearColor(r
, g
, b
, a
);
939 void fClearStencil(GLint s
) {
941 mSymbols
.fClearStencil(s
);
945 void fClientActiveTexture(GLenum texture
) {
947 mSymbols
.fClientActiveTexture(texture
);
951 void fColorMask(realGLboolean red
, realGLboolean green
, realGLboolean blue
,
952 realGLboolean alpha
) {
954 mSymbols
.fColorMask(red
, green
, blue
, alpha
);
958 void fCompressedTexImage2D(GLenum target
, GLint level
, GLenum internalformat
,
959 GLsizei width
, GLsizei height
, GLint border
,
960 GLsizei imageSize
, const GLvoid
* pixels
) {
961 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels
);
963 mSymbols
.fCompressedTexImage2D(target
, level
, internalformat
, width
, height
,
964 border
, imageSize
, pixels
);
966 mHeavyGLCallsSinceLastFlush
= true;
969 void fCompressedTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
970 GLint yoffset
, GLsizei width
, GLsizei height
,
971 GLenum format
, GLsizei imageSize
,
972 const GLvoid
* pixels
) {
973 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels
);
975 mSymbols
.fCompressedTexSubImage2D(target
, level
, xoffset
, yoffset
, width
,
976 height
, format
, imageSize
, pixels
);
978 mHeavyGLCallsSinceLastFlush
= true;
981 void fCopyTexImage2D(GLenum target
, GLint level
, GLenum internalformat
,
982 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
985 void fCopyTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
986 GLint yoffset
, GLint x
, GLint y
, GLsizei width
,
989 raw_fCopyTexSubImage2D(target
, level
, xoffset
, yoffset
, x
, y
, width
,
994 void fCullFace(GLenum mode
) {
996 mSymbols
.fCullFace(mode
);
1000 void fDebugMessageCallback(GLDEBUGPROC callback
, const GLvoid
* userParam
) {
1002 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback
);
1003 mSymbols
.fDebugMessageCallback(callback
, userParam
);
1007 void fDebugMessageControl(GLenum source
, GLenum type
, GLenum severity
,
1008 GLsizei count
, const GLuint
* ids
,
1009 realGLboolean enabled
) {
1011 ASSERT_SYMBOL_PRESENT(fDebugMessageControl
);
1012 mSymbols
.fDebugMessageControl(source
, type
, severity
, count
, ids
, enabled
);
1016 void fDebugMessageInsert(GLenum source
, GLenum type
, GLuint id
,
1017 GLenum severity
, GLsizei length
, const GLchar
* buf
) {
1019 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert
);
1020 mSymbols
.fDebugMessageInsert(source
, type
, id
, severity
, length
, buf
);
1024 void fDetachShader(GLuint program
, GLuint shader
) {
1026 mSymbols
.fDetachShader(program
, shader
);
1030 void fDepthFunc(GLenum func
) {
1032 mSymbols
.fDepthFunc(func
);
1036 void fDepthMask(realGLboolean flag
) {
1038 mSymbols
.fDepthMask(flag
);
1042 void fDisable(GLenum capability
) {
1044 mSymbols
.fDisable(capability
);
1048 void fDisableClientState(GLenum capability
) {
1050 mSymbols
.fDisableClientState(capability
);
1054 void fDisableVertexAttribArray(GLuint index
) {
1056 mSymbols
.fDisableVertexAttribArray(index
);
1060 void fDrawBuffer(GLenum mode
) {
1062 mSymbols
.fDrawBuffer(mode
);
1067 void raw_fDrawArrays(GLenum mode
, GLint first
, GLsizei count
) {
1069 mSymbols
.fDrawArrays(mode
, first
, count
);
1073 void raw_fDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1074 const GLvoid
* indices
) {
1076 mSymbols
.fDrawElements(mode
, count
, type
, indices
);
1081 void fDrawArrays(GLenum mode
, GLint first
, GLsizei count
) {
1083 raw_fDrawArrays(mode
, first
, count
);
1087 void fDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1088 const GLvoid
* indices
) {
1090 raw_fDrawElements(mode
, count
, type
, indices
);
1094 void fEnable(GLenum capability
) {
1096 mSymbols
.fEnable(capability
);
1100 void fEnableClientState(GLenum capability
) {
1102 mSymbols
.fEnableClientState(capability
);
1106 void fEnableVertexAttribArray(GLuint index
) {
1108 mSymbols
.fEnableVertexAttribArray(index
);
1112 void fEndQuery(GLenum target
) {
1114 ASSERT_SYMBOL_PRESENT(fEndQuery
);
1115 mSymbols
.fEndQuery(target
);
1124 mHeavyGLCallsSinceLastFlush
= false;
1131 mHeavyGLCallsSinceLastFlush
= false;
1134 void fFrontFace(GLenum face
) {
1136 mSymbols
.fFrontFace(face
);
1140 void fGetActiveAttrib(GLuint program
, GLuint index
, GLsizei maxLength
,
1141 GLsizei
* length
, GLint
* size
, GLenum
* type
,
1144 mSymbols
.fGetActiveAttrib(program
, index
, maxLength
, length
, size
, type
,
1150 void fGetActiveUniform(GLuint program
, GLuint index
, GLsizei maxLength
,
1151 GLsizei
* length
, GLint
* size
, GLenum
* type
,
1154 mSymbols
.fGetActiveUniform(program
, index
, maxLength
, length
, size
, type
,
1160 void fGetAttachedShaders(GLuint program
, GLsizei maxCount
, GLsizei
* count
,
1163 mSymbols
.fGetAttachedShaders(program
, maxCount
, count
, shaders
);
1168 GLint
fGetAttribLocation(GLuint program
, const GLchar
* name
) {
1171 retval
= mSymbols
.fGetAttribLocation(program
, name
);
1178 void raw_fGetIntegerv(GLenum pname
, GLint
* params
) const {
1180 mSymbols
.fGetIntegerv(pname
, params
);
1186 void fGetIntegerv(GLenum pname
, GLint
* params
) const;
1188 template <typename T
>
1189 void GetInt(const GLenum pname
, T
* const params
) const {
1190 static_assert(sizeof(T
) == sizeof(GLint
), "Invalid T.");
1191 fGetIntegerv(pname
, reinterpret_cast<GLint
*>(params
));
1194 void GetUIntegerv(GLenum pname
, GLuint
* params
) const {
1195 GetInt(pname
, params
);
1198 template <typename T
>
1199 T
GetIntAs(GLenum pname
) const {
1200 static_assert(sizeof(T
) == sizeof(GLint
), "Invalid T.");
1202 fGetIntegerv(pname
, (GLint
*)&ret
);
1206 void fGetFloatv(GLenum pname
, GLfloat
* params
) const {
1208 mSymbols
.fGetFloatv(pname
, params
);
1213 void fGetBooleanv(GLenum pname
, realGLboolean
* params
) const {
1215 mSymbols
.fGetBooleanv(pname
, params
);
1220 void fGetBufferParameteriv(GLenum target
, GLenum pname
, GLint
* params
) {
1222 mSymbols
.fGetBufferParameteriv(target
, pname
, params
);
1227 GLuint
fGetDebugMessageLog(GLuint count
, GLsizei bufsize
, GLenum
* sources
,
1228 GLenum
* types
, GLuint
* ids
, GLenum
* severities
,
1229 GLsizei
* lengths
, GLchar
* messageLog
) {
1232 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog
);
1233 ret
= mSymbols
.fGetDebugMessageLog(count
, bufsize
, sources
, types
, ids
,
1234 severities
, lengths
, messageLog
);
1240 void fGetPointerv(GLenum pname
, GLvoid
** params
) {
1242 ASSERT_SYMBOL_PRESENT(fGetPointerv
);
1243 mSymbols
.fGetPointerv(pname
, params
);
1248 void fGetObjectLabel(GLenum identifier
, GLuint name
, GLsizei bufSize
,
1249 GLsizei
* length
, GLchar
* label
) {
1251 ASSERT_SYMBOL_PRESENT(fGetObjectLabel
);
1252 mSymbols
.fGetObjectLabel(identifier
, name
, bufSize
, length
, label
);
1257 void fGetObjectPtrLabel(const GLvoid
* ptr
, GLsizei bufSize
, GLsizei
* length
,
1260 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel
);
1261 mSymbols
.fGetObjectPtrLabel(ptr
, bufSize
, length
, label
);
1266 void fGenerateMipmap(GLenum target
) {
1268 mSymbols
.fGenerateMipmap(target
);
1272 void fGetProgramiv(GLuint program
, GLenum pname
, GLint
* param
) {
1274 mSymbols
.fGetProgramiv(program
, pname
, param
);
1279 void fGetProgramInfoLog(GLuint program
, GLsizei bufSize
, GLsizei
* length
,
1282 mSymbols
.fGetProgramInfoLog(program
, bufSize
, length
, infoLog
);
1287 void fTexParameteri(GLenum target
, GLenum pname
, GLint param
) {
1289 mSymbols
.fTexParameteri(target
, pname
, param
);
1293 void fTexParameteriv(GLenum target
, GLenum pname
, const GLint
* params
) {
1295 mSymbols
.fTexParameteriv(target
, pname
, params
);
1299 void fTexParameterf(GLenum target
, GLenum pname
, GLfloat param
) {
1301 mSymbols
.fTexParameterf(target
, pname
, param
);
1305 const GLubyte
* fGetString(GLenum name
) {
1306 const GLubyte
* result
= nullptr;
1308 result
= mSymbols
.fGetString(name
);
1314 void fGetTexImage(GLenum target
, GLint level
, GLenum format
, GLenum type
,
1317 ASSERT_SYMBOL_PRESENT(fGetTexImage
);
1318 mSymbols
.fGetTexImage(target
, level
, format
, type
, img
);
1323 void fGetTexLevelParameteriv(GLenum target
, GLint level
, GLenum pname
,
1326 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv
);
1327 mSymbols
.fGetTexLevelParameteriv(target
, level
, pname
, params
);
1332 void fGetTexParameterfv(GLenum target
, GLenum pname
, GLfloat
* params
) {
1334 mSymbols
.fGetTexParameterfv(target
, pname
, params
);
1339 void fGetTexParameteriv(GLenum target
, GLenum pname
, GLint
* params
) {
1341 mSymbols
.fGetTexParameteriv(target
, pname
, params
);
1346 void fGetUniformfv(GLuint program
, GLint location
, GLfloat
* params
) {
1348 mSymbols
.fGetUniformfv(program
, location
, params
);
1353 void fGetUniformiv(GLuint program
, GLint location
, GLint
* params
) {
1355 mSymbols
.fGetUniformiv(program
, location
, params
);
1360 void fGetUniformuiv(GLuint program
, GLint location
, GLuint
* params
) {
1362 ASSERT_SYMBOL_PRESENT(fGetUniformuiv
);
1363 mSymbols
.fGetUniformuiv(program
, location
, params
);
1368 GLint
fGetUniformLocation(GLuint programObj
, const GLchar
* name
) {
1371 retval
= mSymbols
.fGetUniformLocation(programObj
, name
);
1377 void fGetVertexAttribfv(GLuint index
, GLenum pname
, GLfloat
* retval
) {
1379 mSymbols
.fGetVertexAttribfv(index
, pname
, retval
);
1384 void fGetVertexAttribiv(GLuint index
, GLenum pname
, GLint
* retval
) {
1386 mSymbols
.fGetVertexAttribiv(index
, pname
, retval
);
1391 void fGetVertexAttribPointerv(GLuint index
, GLenum pname
, GLvoid
** retval
) {
1393 mSymbols
.fGetVertexAttribPointerv(index
, pname
, retval
);
1398 void fHint(GLenum target
, GLenum mode
) {
1400 mSymbols
.fHint(target
, mode
);
1404 realGLboolean
fIsBuffer(GLuint buffer
) {
1405 realGLboolean retval
= false;
1407 retval
= mSymbols
.fIsBuffer(buffer
);
1413 realGLboolean
fIsEnabled(GLenum capability
) {
1414 realGLboolean retval
= false;
1416 retval
= mSymbols
.fIsEnabled(capability
);
1421 void SetEnabled(const GLenum cap
, const bool val
) {
1429 bool PushEnabled(const GLenum cap
, const bool newVal
) {
1430 const bool oldVal
= fIsEnabled(cap
);
1431 if (oldVal
!= newVal
) {
1432 SetEnabled(cap
, newVal
);
1437 realGLboolean
fIsProgram(GLuint program
) {
1438 realGLboolean retval
= false;
1440 retval
= mSymbols
.fIsProgram(program
);
1445 realGLboolean
fIsShader(GLuint shader
) {
1446 realGLboolean retval
= false;
1448 retval
= mSymbols
.fIsShader(shader
);
1453 realGLboolean
fIsTexture(GLuint texture
) {
1454 realGLboolean retval
= false;
1456 retval
= mSymbols
.fIsTexture(texture
);
1461 void fLineWidth(GLfloat width
) {
1463 mSymbols
.fLineWidth(width
);
1467 void fLinkProgram(GLuint program
) {
1469 mSymbols
.fLinkProgram(program
);
1473 void fObjectLabel(GLenum identifier
, GLuint name
, GLsizei length
,
1474 const GLchar
* label
) {
1476 ASSERT_SYMBOL_PRESENT(fObjectLabel
);
1477 mSymbols
.fObjectLabel(identifier
, name
, length
, label
);
1481 void fObjectPtrLabel(const GLvoid
* ptr
, GLsizei length
, const GLchar
* label
) {
1483 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel
);
1484 mSymbols
.fObjectPtrLabel(ptr
, length
, label
);
1488 void fLoadIdentity() {
1490 mSymbols
.fLoadIdentity();
1494 void fLoadMatrixf(const GLfloat
* matrix
) {
1496 mSymbols
.fLoadMatrixf(matrix
);
1500 void fMatrixMode(GLenum mode
) {
1502 mSymbols
.fMatrixMode(mode
);
1506 void fPixelStorei(GLenum pname
, GLint param
) {
1508 mSymbols
.fPixelStorei(pname
, param
);
1512 void fTextureRangeAPPLE(GLenum target
, GLsizei length
, GLvoid
* pointer
) {
1513 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer
);
1515 mSymbols
.fTextureRangeAPPLE(target
, length
, pointer
);
1519 void fPointParameterf(GLenum pname
, GLfloat param
) {
1521 mSymbols
.fPointParameterf(pname
, param
);
1525 void fPolygonMode(GLenum face
, GLenum mode
) {
1527 mSymbols
.fPolygonMode(face
, mode
);
1531 void fPolygonOffset(GLfloat factor
, GLfloat bias
) {
1533 mSymbols
.fPolygonOffset(factor
, bias
);
1537 void fPopDebugGroup() {
1539 ASSERT_SYMBOL_PRESENT(fPopDebugGroup
);
1540 mSymbols
.fPopDebugGroup();
1544 void fPushDebugGroup(GLenum source
, GLuint id
, GLsizei length
,
1545 const GLchar
* message
) {
1547 ASSERT_SYMBOL_PRESENT(fPushDebugGroup
);
1548 mSymbols
.fPushDebugGroup(source
, id
, length
, message
);
1552 void fReadBuffer(GLenum mode
) {
1554 mSymbols
.fReadBuffer(mode
);
1558 void raw_fReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1559 GLenum format
, GLenum type
, GLvoid
* pixels
) {
1561 mSymbols
.fReadPixels(x
, y
, width
, height
, format
, type
, pixels
);
1564 mHeavyGLCallsSinceLastFlush
= true;
1567 void fReadPixels(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1568 GLenum format
, GLenum type
, GLvoid
* pixels
);
1571 void fSampleCoverage(GLclampf value
, realGLboolean invert
) {
1573 mSymbols
.fSampleCoverage(value
, invert
);
1577 void fScissor(GLint x
, GLint y
, GLsizei width
, GLsizei height
) {
1578 if (mScissorRect
[0] == x
&& mScissorRect
[1] == y
&&
1579 mScissorRect
[2] == width
&& mScissorRect
[3] == height
) {
1582 mScissorRect
[0] = x
;
1583 mScissorRect
[1] = y
;
1584 mScissorRect
[2] = width
;
1585 mScissorRect
[3] = height
;
1587 mSymbols
.fScissor(x
, y
, width
, height
);
1591 void fStencilFunc(GLenum func
, GLint reference
, GLuint mask
) {
1593 mSymbols
.fStencilFunc(func
, reference
, mask
);
1597 void fStencilFuncSeparate(GLenum frontfunc
, GLenum backfunc
, GLint reference
,
1600 mSymbols
.fStencilFuncSeparate(frontfunc
, backfunc
, reference
, mask
);
1604 void fStencilMask(GLuint mask
) {
1606 mSymbols
.fStencilMask(mask
);
1610 void fStencilMaskSeparate(GLenum face
, GLuint mask
) {
1612 mSymbols
.fStencilMaskSeparate(face
, mask
);
1616 void fStencilOp(GLenum fail
, GLenum zfail
, GLenum zpass
) {
1618 mSymbols
.fStencilOp(fail
, zfail
, zpass
);
1622 void fStencilOpSeparate(GLenum face
, GLenum sfail
, GLenum dpfail
,
1625 mSymbols
.fStencilOpSeparate(face
, sfail
, dpfail
, dppass
);
1629 void fTexGeni(GLenum coord
, GLenum pname
, GLint param
) {
1631 mSymbols
.fTexGeni(coord
, pname
, param
);
1635 void fTexGenf(GLenum coord
, GLenum pname
, GLfloat param
) {
1637 mSymbols
.fTexGenf(coord
, pname
, param
);
1641 void fTexGenfv(GLenum coord
, GLenum pname
, const GLfloat
* params
) {
1643 mSymbols
.fTexGenfv(coord
, pname
, params
);
1648 void raw_fTexImage2D(GLenum target
, GLint level
, GLint internalformat
,
1649 GLsizei width
, GLsizei height
, GLint border
,
1650 GLenum format
, GLenum type
, const GLvoid
* pixels
) {
1651 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels
);
1653 mSymbols
.fTexImage2D(target
, level
, internalformat
, width
, height
, border
,
1654 format
, type
, pixels
);
1656 mHeavyGLCallsSinceLastFlush
= true;
1660 void fTexImage2D(GLenum target
, GLint level
, GLint internalformat
,
1661 GLsizei width
, GLsizei height
, GLint border
, GLenum format
,
1662 GLenum type
, const GLvoid
* pixels
);
1664 void fTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
, GLint yoffset
,
1665 GLsizei width
, GLsizei height
, GLenum format
, GLenum type
,
1666 const GLvoid
* pixels
) {
1667 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels
);
1669 mSymbols
.fTexSubImage2D(target
, level
, xoffset
, yoffset
, width
, height
,
1670 format
, type
, pixels
);
1672 mHeavyGLCallsSinceLastFlush
= true;
1675 void fUniform1f(GLint location
, GLfloat v0
) {
1677 mSymbols
.fUniform1f(location
, v0
);
1681 void fUniform1fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1683 mSymbols
.fUniform1fv(location
, count
, value
);
1687 void fUniform1i(GLint location
, GLint v0
) {
1689 mSymbols
.fUniform1i(location
, v0
);
1693 void fUniform1iv(GLint location
, GLsizei count
, const GLint
* value
) {
1695 mSymbols
.fUniform1iv(location
, count
, value
);
1699 void fUniform2f(GLint location
, GLfloat v0
, GLfloat v1
) {
1701 mSymbols
.fUniform2f(location
, v0
, v1
);
1705 void fUniform2fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1707 mSymbols
.fUniform2fv(location
, count
, value
);
1711 void fUniform2i(GLint location
, GLint v0
, GLint v1
) {
1713 mSymbols
.fUniform2i(location
, v0
, v1
);
1717 void fUniform2iv(GLint location
, GLsizei count
, const GLint
* value
) {
1719 mSymbols
.fUniform2iv(location
, count
, value
);
1723 void fUniform3f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
) {
1725 mSymbols
.fUniform3f(location
, v0
, v1
, v2
);
1729 void fUniform3fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1731 mSymbols
.fUniform3fv(location
, count
, value
);
1735 void fUniform3i(GLint location
, GLint v0
, GLint v1
, GLint v2
) {
1737 mSymbols
.fUniform3i(location
, v0
, v1
, v2
);
1741 void fUniform3iv(GLint location
, GLsizei count
, const GLint
* value
) {
1743 mSymbols
.fUniform3iv(location
, count
, value
);
1747 void fUniform4f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
1750 mSymbols
.fUniform4f(location
, v0
, v1
, v2
, v3
);
1754 void fUniform4fv(GLint location
, GLsizei count
, const GLfloat
* value
) {
1756 mSymbols
.fUniform4fv(location
, count
, value
);
1760 void fUniform4i(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
) {
1762 mSymbols
.fUniform4i(location
, v0
, v1
, v2
, v3
);
1766 void fUniform4iv(GLint location
, GLsizei count
, const GLint
* value
) {
1768 mSymbols
.fUniform4iv(location
, count
, value
);
1772 void fUniformMatrix2fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1773 const GLfloat
* value
) {
1775 mSymbols
.fUniformMatrix2fv(location
, count
, transpose
, value
);
1779 void fUniformMatrix2x3fv(GLint location
, GLsizei count
,
1780 realGLboolean transpose
, const GLfloat
* value
) {
1782 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv
);
1783 mSymbols
.fUniformMatrix2x3fv(location
, count
, transpose
, value
);
1787 void fUniformMatrix2x4fv(GLint location
, GLsizei count
,
1788 realGLboolean transpose
, const GLfloat
* value
) {
1790 ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv
);
1791 mSymbols
.fUniformMatrix2x4fv(location
, count
, transpose
, value
);
1795 void fUniformMatrix3fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1796 const GLfloat
* value
) {
1798 mSymbols
.fUniformMatrix3fv(location
, count
, transpose
, value
);
1802 void fUniformMatrix3x2fv(GLint location
, GLsizei count
,
1803 realGLboolean transpose
, const GLfloat
* value
) {
1805 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv
);
1806 mSymbols
.fUniformMatrix3x2fv(location
, count
, transpose
, value
);
1810 void fUniformMatrix3x4fv(GLint location
, GLsizei count
,
1811 realGLboolean transpose
, const GLfloat
* value
) {
1813 ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv
);
1814 mSymbols
.fUniformMatrix3x4fv(location
, count
, transpose
, value
);
1818 void fUniformMatrix4fv(GLint location
, GLsizei count
, realGLboolean transpose
,
1819 const GLfloat
* value
) {
1821 mSymbols
.fUniformMatrix4fv(location
, count
, transpose
, value
);
1825 void fUniformMatrix4x2fv(GLint location
, GLsizei count
,
1826 realGLboolean transpose
, const GLfloat
* value
) {
1828 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv
);
1829 mSymbols
.fUniformMatrix4x2fv(location
, count
, transpose
, value
);
1833 void fUniformMatrix4x3fv(GLint location
, GLsizei count
,
1834 realGLboolean transpose
, const GLfloat
* value
) {
1836 ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv
);
1837 mSymbols
.fUniformMatrix4x3fv(location
, count
, transpose
, value
);
1841 void fUseProgram(GLuint program
) {
1843 mSymbols
.fUseProgram(program
);
1847 void fValidateProgram(GLuint program
) {
1849 mSymbols
.fValidateProgram(program
);
1853 void fVertexAttribPointer(GLuint index
, GLint size
, GLenum type
,
1854 realGLboolean normalized
, GLsizei stride
,
1855 const GLvoid
* pointer
) {
1857 mSymbols
.fVertexAttribPointer(index
, size
, type
, normalized
, stride
,
1862 void fVertexAttrib1f(GLuint index
, GLfloat x
) {
1864 mSymbols
.fVertexAttrib1f(index
, x
);
1868 void fVertexAttrib2f(GLuint index
, GLfloat x
, GLfloat y
) {
1870 mSymbols
.fVertexAttrib2f(index
, x
, y
);
1874 void fVertexAttrib3f(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
) {
1876 mSymbols
.fVertexAttrib3f(index
, x
, y
, z
);
1880 void fVertexAttrib4f(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
,
1883 mSymbols
.fVertexAttrib4f(index
, x
, y
, z
, w
);
1887 void fVertexAttrib1fv(GLuint index
, const GLfloat
* v
) {
1889 mSymbols
.fVertexAttrib1fv(index
, v
);
1893 void fVertexAttrib2fv(GLuint index
, const GLfloat
* v
) {
1895 mSymbols
.fVertexAttrib2fv(index
, v
);
1899 void fVertexAttrib3fv(GLuint index
, const GLfloat
* v
) {
1901 mSymbols
.fVertexAttrib3fv(index
, v
);
1905 void fVertexAttrib4fv(GLuint index
, const GLfloat
* v
) {
1907 mSymbols
.fVertexAttrib4fv(index
, v
);
1911 void fVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
1912 const GLvoid
* pointer
) {
1914 mSymbols
.fVertexPointer(size
, type
, stride
, pointer
);
1918 void fViewport(GLint x
, GLint y
, GLsizei width
, GLsizei height
) {
1919 if (mViewportRect
[0] == x
&& mViewportRect
[1] == y
&&
1920 mViewportRect
[2] == width
&& mViewportRect
[3] == height
) {
1923 mViewportRect
[0] = x
;
1924 mViewportRect
[1] = y
;
1925 mViewportRect
[2] = width
;
1926 mViewportRect
[3] = height
;
1928 mSymbols
.fViewport(x
, y
, width
, height
);
1932 void fCompileShader(GLuint shader
) {
1934 mSymbols
.fCompileShader(shader
);
1939 friend class SharedSurface_IOSurface
;
1941 void raw_fCopyTexImage2D(GLenum target
, GLint level
, GLenum internalformat
,
1942 GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1945 mSymbols
.fCopyTexImage2D(target
, level
, internalformat
, x
, y
, width
, height
,
1950 void raw_fCopyTexSubImage2D(GLenum target
, GLint level
, GLint xoffset
,
1951 GLint yoffset
, GLint x
, GLint y
, GLsizei width
,
1954 mSymbols
.fCopyTexSubImage2D(target
, level
, xoffset
, yoffset
, x
, y
, width
,
1960 void fGetShaderiv(GLuint shader
, GLenum pname
, GLint
* param
) {
1962 mSymbols
.fGetShaderiv(shader
, pname
, param
);
1967 void fGetShaderInfoLog(GLuint shader
, GLsizei bufSize
, GLsizei
* length
,
1970 mSymbols
.fGetShaderInfoLog(shader
, bufSize
, length
, infoLog
);
1976 void raw_fGetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
,
1977 GLint
* range
, GLint
* precision
) {
1978 MOZ_ASSERT(IsGLES());
1981 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat
);
1982 mSymbols
.fGetShaderPrecisionFormat(shadertype
, precisiontype
, range
,
1989 void fGetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
,
1990 GLint
* range
, GLint
* precision
) {
1992 raw_fGetShaderPrecisionFormat(shadertype
, precisiontype
, range
,
1995 // Fall back to automatic values because almost all desktop hardware
1996 // supports the OpenGL standard precisions.
1997 GetShaderPrecisionFormatNonES2(shadertype
, precisiontype
, range
,
2002 void fGetShaderSource(GLint obj
, GLsizei maxLength
, GLsizei
* length
,
2005 mSymbols
.fGetShaderSource(obj
, maxLength
, length
, source
);
2010 void fShaderSource(GLuint shader
, GLsizei count
, const GLchar
* const* strings
,
2011 const GLint
* lengths
) {
2013 mSymbols
.fShaderSource(shader
, count
, strings
, lengths
);
2018 mutable GLuint mCachedDrawFb
= 0;
2019 mutable GLuint mCachedReadFb
= 0;
2022 bool mElideDuplicateBindFramebuffers
= false;
2024 void fBindFramebuffer(const GLenum target
, const GLuint fb
) const {
2025 if (mElideDuplicateBindFramebuffers
) {
2026 MOZ_ASSERT(mCachedDrawFb
==
2027 GetIntAs
<GLuint
>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING
));
2028 MOZ_ASSERT(mCachedReadFb
==
2029 GetIntAs
<GLuint
>(LOCAL_GL_READ_FRAMEBUFFER_BINDING
));
2032 case LOCAL_GL_FRAMEBUFFER
:
2033 if (mCachedDrawFb
== fb
&& mCachedReadFb
== fb
) return;
2035 case LOCAL_GL_DRAW_FRAMEBUFFER
:
2036 if (mCachedDrawFb
== fb
) return;
2038 case LOCAL_GL_READ_FRAMEBUFFER
:
2039 if (mCachedReadFb
== fb
) return;
2045 mSymbols
.fBindFramebuffer(target
, fb
);
2049 case LOCAL_GL_FRAMEBUFFER
:
2053 case LOCAL_GL_DRAW_FRAMEBUFFER
:
2056 case LOCAL_GL_READ_FRAMEBUFFER
:
2062 void fBindRenderbuffer(GLenum target
, GLuint renderbuffer
) {
2064 mSymbols
.fBindRenderbuffer(target
, renderbuffer
);
2068 GLenum
fCheckFramebufferStatus(GLenum target
) {
2071 retval
= mSymbols
.fCheckFramebufferStatus(target
);
2077 void fFramebufferRenderbuffer(GLenum target
, GLenum attachmentPoint
,
2078 GLenum renderbufferTarget
,
2079 GLuint renderbuffer
) {
2081 mSymbols
.fFramebufferRenderbuffer(target
, attachmentPoint
,
2082 renderbufferTarget
, renderbuffer
);
2086 void fFramebufferTexture2D(GLenum target
, GLenum attachmentPoint
,
2087 GLenum textureTarget
, GLuint texture
,
2090 mSymbols
.fFramebufferTexture2D(target
, attachmentPoint
, textureTarget
,
2093 if (mNeedsCheckAfterAttachTextureToFb
) {
2094 fCheckFramebufferStatus(target
);
2098 void fFramebufferTextureLayer(GLenum target
, GLenum attachment
,
2099 GLuint texture
, GLint level
, GLint layer
) {
2101 ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer
);
2102 mSymbols
.fFramebufferTextureLayer(target
, attachment
, texture
, level
,
2107 void fGetFramebufferAttachmentParameteriv(GLenum target
, GLenum attachment
,
2108 GLenum pname
, GLint
* value
) {
2110 mSymbols
.fGetFramebufferAttachmentParameteriv(target
, attachment
, pname
,
2116 void fGetRenderbufferParameteriv(GLenum target
, GLenum pname
, GLint
* value
) {
2118 mSymbols
.fGetRenderbufferParameteriv(target
, pname
, value
);
2123 realGLboolean
fIsFramebuffer(GLuint framebuffer
) {
2124 realGLboolean retval
= false;
2126 retval
= mSymbols
.fIsFramebuffer(framebuffer
);
2133 realGLboolean
fIsRenderbuffer(GLuint renderbuffer
) {
2134 realGLboolean retval
= false;
2136 retval
= mSymbols
.fIsRenderbuffer(renderbuffer
);
2142 void fRenderbufferStorage(GLenum target
, GLenum internalFormat
, GLsizei width
,
2145 mSymbols
.fRenderbufferStorage(target
, internalFormat
, width
, height
);
2150 void raw_fDepthRange(GLclampf a
, GLclampf b
) {
2151 MOZ_ASSERT(!IsGLES());
2154 ASSERT_SYMBOL_PRESENT(fDepthRange
);
2155 mSymbols
.fDepthRange(a
, b
);
2159 void raw_fDepthRangef(GLclampf a
, GLclampf b
) {
2160 MOZ_ASSERT(IsGLES());
2163 ASSERT_SYMBOL_PRESENT(fDepthRangef
);
2164 mSymbols
.fDepthRangef(a
, b
);
2168 void raw_fClearDepth(GLclampf v
) {
2169 MOZ_ASSERT(!IsGLES());
2172 ASSERT_SYMBOL_PRESENT(fClearDepth
);
2173 mSymbols
.fClearDepth(v
);
2177 void raw_fClearDepthf(GLclampf v
) {
2178 MOZ_ASSERT(IsGLES());
2181 ASSERT_SYMBOL_PRESENT(fClearDepthf
);
2182 mSymbols
.fClearDepthf(v
);
2187 void fDepthRange(GLclampf a
, GLclampf b
) {
2189 raw_fDepthRangef(a
, b
);
2191 raw_fDepthRange(a
, b
);
2195 void fClearDepth(GLclampf v
) {
2197 raw_fClearDepthf(v
);
2203 void* fMapBuffer(GLenum target
, GLenum access
) {
2204 void* ret
= nullptr;
2206 ASSERT_SYMBOL_PRESENT(fMapBuffer
);
2207 ret
= mSymbols
.fMapBuffer(target
, access
);
2213 realGLboolean
fUnmapBuffer(GLenum target
) {
2214 realGLboolean ret
= false;
2216 ASSERT_SYMBOL_PRESENT(fUnmapBuffer
);
2217 ret
= mSymbols
.fUnmapBuffer(target
);
2223 GLuint
raw_fCreateProgram() {
2226 ret
= mSymbols
.fCreateProgram();
2231 GLuint
raw_fCreateShader(GLenum t
) {
2234 ret
= mSymbols
.fCreateShader(t
);
2239 void raw_fGenBuffers(GLsizei n
, GLuint
* names
) {
2241 mSymbols
.fGenBuffers(n
, names
);
2246 void raw_fGenFramebuffers(GLsizei n
, GLuint
* names
) {
2248 mSymbols
.fGenFramebuffers(n
, names
);
2253 void raw_fGenRenderbuffers(GLsizei n
, GLuint
* names
) {
2255 mSymbols
.fGenRenderbuffers(n
, names
);
2260 void raw_fGenTextures(GLsizei n
, GLuint
* names
) {
2262 mSymbols
.fGenTextures(n
, names
);
2268 GLuint
fCreateProgram() {
2269 GLuint ret
= raw_fCreateProgram();
2270 TRACKING_CONTEXT(CreatedProgram(this, ret
));
2274 GLuint
fCreateShader(GLenum t
) {
2275 GLuint ret
= raw_fCreateShader(t
);
2276 TRACKING_CONTEXT(CreatedShader(this, ret
));
2280 void fGenBuffers(GLsizei n
, GLuint
* names
) {
2281 raw_fGenBuffers(n
, names
);
2282 TRACKING_CONTEXT(CreatedBuffers(this, n
, names
));
2285 void fGenFramebuffers(GLsizei n
, GLuint
* names
) {
2286 raw_fGenFramebuffers(n
, names
);
2287 TRACKING_CONTEXT(CreatedFramebuffers(this, n
, names
));
2290 void fGenRenderbuffers(GLsizei n
, GLuint
* names
) {
2291 raw_fGenRenderbuffers(n
, names
);
2292 TRACKING_CONTEXT(CreatedRenderbuffers(this, n
, names
));
2295 void fGenTextures(GLsizei n
, GLuint
* names
) {
2296 raw_fGenTextures(n
, names
);
2297 TRACKING_CONTEXT(CreatedTextures(this, n
, names
));
2301 void raw_fDeleteProgram(GLuint program
) {
2303 mSymbols
.fDeleteProgram(program
);
2307 void raw_fDeleteShader(GLuint shader
) {
2309 mSymbols
.fDeleteShader(shader
);
2313 void raw_fDeleteBuffers(GLsizei n
, const GLuint
* names
) {
2315 mSymbols
.fDeleteBuffers(n
, names
);
2319 void raw_fDeleteFramebuffers(GLsizei n
, const GLuint
* names
) {
2321 mSymbols
.fDeleteFramebuffers(n
, names
);
2324 for (const auto i
: IntegerRange(n
)) {
2325 const auto fb
= names
[i
];
2326 if (mCachedDrawFb
== fb
) {
2329 if (mCachedReadFb
== fb
) {
2335 void raw_fDeleteRenderbuffers(GLsizei n
, const GLuint
* names
) {
2337 mSymbols
.fDeleteRenderbuffers(n
, names
);
2341 void raw_fDeleteTextures(GLsizei n
, const GLuint
* names
) {
2343 mSymbols
.fDeleteTextures(n
, names
);
2348 void fDeleteProgram(GLuint program
) {
2349 raw_fDeleteProgram(program
);
2350 TRACKING_CONTEXT(DeletedProgram(this, program
));
2353 void fDeleteShader(GLuint shader
) {
2354 raw_fDeleteShader(shader
);
2355 TRACKING_CONTEXT(DeletedShader(this, shader
));
2358 void fDeleteBuffers(GLsizei n
, const GLuint
* names
) {
2359 raw_fDeleteBuffers(n
, names
);
2360 TRACKING_CONTEXT(DeletedBuffers(this, n
, names
));
2363 void fDeleteFramebuffers(GLsizei n
, const GLuint
* names
);
2365 void fDeleteRenderbuffers(GLsizei n
, const GLuint
* names
) {
2366 raw_fDeleteRenderbuffers(n
, names
);
2367 TRACKING_CONTEXT(DeletedRenderbuffers(this, n
, names
));
2370 void fDeleteTextures(GLsizei n
, const GLuint
* names
) {
2372 // On the Mac the call to fDeleteTextures() triggers a flush. But it
2373 // happens at the wrong time, which can lead to crashes. To work around
2374 // this we call fFlush() explicitly ourselves, before the call to
2375 // fDeleteTextures(). This fixes bug 1666293.
2378 raw_fDeleteTextures(n
, names
);
2379 TRACKING_CONTEXT(DeletedTextures(this, n
, names
));
2382 // -----------------------------------------------------------------------------
2383 // Extension ARB_sync (GL)
2385 GLsync
fFenceSync(GLenum condition
, GLbitfield flags
) {
2388 ASSERT_SYMBOL_PRESENT(fFenceSync
);
2389 ret
= mSymbols
.fFenceSync(condition
, flags
);
2395 realGLboolean
fIsSync(GLsync sync
) {
2396 realGLboolean ret
= false;
2398 ASSERT_SYMBOL_PRESENT(fIsSync
);
2399 ret
= mSymbols
.fIsSync(sync
);
2405 void fDeleteSync(GLsync sync
) {
2407 ASSERT_SYMBOL_PRESENT(fDeleteSync
);
2408 mSymbols
.fDeleteSync(sync
);
2412 GLenum
fClientWaitSync(GLsync sync
, GLbitfield flags
, GLuint64 timeout
) {
2415 ASSERT_SYMBOL_PRESENT(fClientWaitSync
);
2416 ret
= mSymbols
.fClientWaitSync(sync
, flags
, timeout
);
2422 void fWaitSync(GLsync sync
, GLbitfield flags
, GLuint64 timeout
) {
2424 ASSERT_SYMBOL_PRESENT(fWaitSync
);
2425 mSymbols
.fWaitSync(sync
, flags
, timeout
);
2429 void fGetInteger64v(GLenum pname
, GLint64
* params
) {
2431 ASSERT_SYMBOL_PRESENT(fGetInteger64v
);
2432 mSymbols
.fGetInteger64v(pname
, params
);
2436 void fGetSynciv(GLsync sync
, GLenum pname
, GLsizei bufSize
, GLsizei
* length
,
2439 ASSERT_SYMBOL_PRESENT(fGetSynciv
);
2440 mSymbols
.fGetSynciv(sync
, pname
, bufSize
, length
, values
);
2445 // -----------------------------------------------------------------------------
2446 // Extension OES_EGL_image (GLES)
2448 void fEGLImageTargetTexture2D(GLenum target
, GLeglImage image
) {
2450 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D
);
2451 mSymbols
.fEGLImageTargetTexture2D(target
, image
);
2453 mHeavyGLCallsSinceLastFlush
= true;
2456 void fEGLImageTargetRenderbufferStorage(GLenum target
, GLeglImage image
) {
2458 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage
);
2459 mSymbols
.fEGLImageTargetRenderbufferStorage(target
, image
);
2463 // -----------------------------------------------------------------------------
2464 // Package XXX_bind_buffer_offset
2466 void fBindBufferOffset(GLenum target
, GLuint index
, GLuint buffer
,
2469 ASSERT_SYMBOL_PRESENT(fBindBufferOffset
);
2470 mSymbols
.fBindBufferOffset(target
, index
, buffer
, offset
);
2474 // -----------------------------------------------------------------------------
2475 // Package XXX_draw_buffers
2477 void fDrawBuffers(GLsizei n
, const GLenum
* bufs
) {
2479 ASSERT_SYMBOL_PRESENT(fDrawBuffers
);
2480 mSymbols
.fDrawBuffers(n
, bufs
);
2484 // -----------------------------------------------------------------------------
2485 // Package XXX_draw_instanced
2487 void fDrawArraysInstanced(GLenum mode
, GLint first
, GLsizei count
,
2488 GLsizei primcount
) {
2490 raw_fDrawArraysInstanced(mode
, first
, count
, primcount
);
2494 void fDrawElementsInstanced(GLenum mode
, GLsizei count
, GLenum type
,
2495 const GLvoid
* indices
, GLsizei primcount
) {
2497 raw_fDrawElementsInstanced(mode
, count
, type
, indices
, primcount
);
2502 void raw_fDrawArraysInstanced(GLenum mode
, GLint first
, GLsizei count
,
2503 GLsizei primcount
) {
2505 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced
);
2506 mSymbols
.fDrawArraysInstanced(mode
, first
, count
, primcount
);
2510 void raw_fDrawElementsInstanced(GLenum mode
, GLsizei count
, GLenum type
,
2511 const GLvoid
* indices
, GLsizei primcount
) {
2513 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced
);
2514 mSymbols
.fDrawElementsInstanced(mode
, count
, type
, indices
, primcount
);
2518 // -----------------------------------------------------------------------------
2519 // Package XXX_framebuffer_blit
2522 void fBlitFramebuffer(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
2523 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
2524 GLbitfield mask
, GLenum filter
) {
2527 raw_fBlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
, dstY0
, dstX1
, dstY1
,
2534 void raw_fBlitFramebuffer(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
2535 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
2536 GLbitfield mask
, GLenum filter
) {
2538 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer
);
2539 mSymbols
.fBlitFramebuffer(srcX0
, srcY0
, srcX1
, srcY1
, dstX0
, dstY0
, dstX1
,
2540 dstY1
, mask
, filter
);
2544 // -----------------------------------------------------------------------------
2545 // Package XXX_framebuffer_multisample
2547 void fRenderbufferStorageMultisample(GLenum target
, GLsizei samples
,
2548 GLenum internalFormat
, GLsizei width
,
2551 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample
);
2552 mSymbols
.fRenderbufferStorageMultisample(target
, samples
, internalFormat
,
2557 // -----------------------------------------------------------------------------
2558 // GL 3.0, GL ES 3.0 & EXT_gpu_shader4
2560 void fGetVertexAttribIiv(GLuint index
, GLenum pname
, GLint
* params
) {
2561 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv
);
2563 mSymbols
.fGetVertexAttribIiv(index
, pname
, params
);
2568 void fGetVertexAttribIuiv(GLuint index
, GLenum pname
, GLuint
* params
) {
2569 ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv
);
2571 mSymbols
.fGetVertexAttribIuiv(index
, pname
, params
);
2576 void fVertexAttribI4i(GLuint index
, GLint x
, GLint y
, GLint z
, GLint w
) {
2578 ASSERT_SYMBOL_PRESENT(fVertexAttribI4i
);
2579 mSymbols
.fVertexAttribI4i(index
, x
, y
, z
, w
);
2583 void fVertexAttribI4iv(GLuint index
, const GLint
* v
) {
2585 ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv
);
2586 mSymbols
.fVertexAttribI4iv(index
, v
);
2590 void fVertexAttribI4ui(GLuint index
, GLuint x
, GLuint y
, GLuint z
, GLuint w
) {
2592 ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui
);
2593 mSymbols
.fVertexAttribI4ui(index
, x
, y
, z
, w
);
2597 void fVertexAttribI4uiv(GLuint index
, const GLuint
* v
) {
2599 ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv
);
2600 mSymbols
.fVertexAttribI4uiv(index
, v
);
2604 void fVertexAttribIPointer(GLuint index
, GLint size
, GLenum type
,
2605 GLsizei stride
, const GLvoid
* offset
) {
2607 ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer
);
2608 mSymbols
.fVertexAttribIPointer(index
, size
, type
, stride
, offset
);
2612 void fUniform1ui(GLint location
, GLuint v0
) {
2614 ASSERT_SYMBOL_PRESENT(fUniform1ui
);
2615 mSymbols
.fUniform1ui(location
, v0
);
2619 void fUniform2ui(GLint location
, GLuint v0
, GLuint v1
) {
2621 ASSERT_SYMBOL_PRESENT(fUniform2ui
);
2622 mSymbols
.fUniform2ui(location
, v0
, v1
);
2626 void fUniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
) {
2628 ASSERT_SYMBOL_PRESENT(fUniform3ui
);
2629 mSymbols
.fUniform3ui(location
, v0
, v1
, v2
);
2633 void fUniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
) {
2635 ASSERT_SYMBOL_PRESENT(fUniform4ui
);
2636 mSymbols
.fUniform4ui(location
, v0
, v1
, v2
, v3
);
2640 void fUniform1uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2642 ASSERT_SYMBOL_PRESENT(fUniform1uiv
);
2643 mSymbols
.fUniform1uiv(location
, count
, value
);
2647 void fUniform2uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2649 ASSERT_SYMBOL_PRESENT(fUniform2uiv
);
2650 mSymbols
.fUniform2uiv(location
, count
, value
);
2654 void fUniform3uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2656 ASSERT_SYMBOL_PRESENT(fUniform3uiv
);
2657 mSymbols
.fUniform3uiv(location
, count
, value
);
2661 void fUniform4uiv(GLint location
, GLsizei count
, const GLuint
* value
) {
2663 ASSERT_SYMBOL_PRESENT(fUniform4uiv
);
2664 mSymbols
.fUniform4uiv(location
, count
, value
);
2668 GLint
fGetFragDataLocation(GLuint program
, const GLchar
* name
) {
2671 ASSERT_SYMBOL_PRESENT(fGetFragDataLocation
);
2672 result
= mSymbols
.fGetFragDataLocation(program
, name
);
2678 // -----------------------------------------------------------------------------
2679 // Package XXX_instanced_arrays
2681 void fVertexAttribDivisor(GLuint index
, GLuint divisor
) {
2683 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor
);
2684 mSymbols
.fVertexAttribDivisor(index
, divisor
);
2688 // -----------------------------------------------------------------------------
2689 // Feature internalformat_query
2691 void fGetInternalformativ(GLenum target
, GLenum internalformat
, GLenum pname
,
2692 GLsizei bufSize
, GLint
* params
) {
2694 ASSERT_SYMBOL_PRESENT(fGetInternalformativ
);
2695 mSymbols
.fGetInternalformativ(target
, internalformat
, pname
, bufSize
,
2701 // -----------------------------------------------------------------------------
2702 // Package XXX_query_counter
2704 * XXX_query_counter:
2705 * - depends on XXX_query_objects
2706 * - provide all followed entry points
2707 * - provide GL_TIMESTAMP
2710 void fQueryCounter(GLuint id
, GLenum target
) {
2712 ASSERT_SYMBOL_PRESENT(fQueryCounter
);
2713 mSymbols
.fQueryCounter(id
, target
);
2717 // -----------------------------------------------------------------------------
2718 // Package XXX_query_objects
2720 * XXX_query_objects:
2721 * - provide all followed entry points
2723 * XXX_occlusion_query2:
2724 * - depends on XXX_query_objects
2725 * - provide ANY_SAMPLES_PASSED
2727 * XXX_occlusion_query_boolean:
2728 * - depends on XXX_occlusion_query2
2729 * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2732 void fDeleteQueries(GLsizei n
, const GLuint
* names
) {
2734 ASSERT_SYMBOL_PRESENT(fDeleteQueries
);
2735 mSymbols
.fDeleteQueries(n
, names
);
2737 TRACKING_CONTEXT(DeletedQueries(this, n
, names
));
2740 void fGenQueries(GLsizei n
, GLuint
* names
) {
2742 ASSERT_SYMBOL_PRESENT(fGenQueries
);
2743 mSymbols
.fGenQueries(n
, names
);
2745 TRACKING_CONTEXT(CreatedQueries(this, n
, names
));
2748 void fGetQueryiv(GLenum target
, GLenum pname
, GLint
* params
) {
2750 ASSERT_SYMBOL_PRESENT(fGetQueryiv
);
2751 mSymbols
.fGetQueryiv(target
, pname
, params
);
2756 void fGetQueryObjectuiv(GLuint id
, GLenum pname
, GLuint
* params
) {
2758 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv
);
2759 mSymbols
.fGetQueryObjectuiv(id
, pname
, params
);
2764 realGLboolean
fIsQuery(GLuint query
) {
2765 realGLboolean retval
= false;
2767 ASSERT_SYMBOL_PRESENT(fIsQuery
);
2768 retval
= mSymbols
.fIsQuery(query
);
2774 // -----------------------------------------------------------------------------
2775 // Package XXX_get_query_object_i64v
2777 * XXX_get_query_object_i64v:
2778 * - depends on XXX_query_objects
2779 * - provide the followed entry point
2782 void fGetQueryObjecti64v(GLuint id
, GLenum pname
, GLint64
* params
) {
2784 ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v
);
2785 mSymbols
.fGetQueryObjecti64v(id
, pname
, params
);
2790 void fGetQueryObjectui64v(GLuint id
, GLenum pname
, GLuint64
* params
) {
2792 ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v
);
2793 mSymbols
.fGetQueryObjectui64v(id
, pname
, params
);
2798 // -----------------------------------------------------------------------------
2799 // Package XXX_get_query_object_iv
2801 * XXX_get_query_object_iv:
2802 * - depends on XXX_query_objects
2803 * - provide the followed entry point
2805 * XXX_occlusion_query:
2806 * - depends on XXX_get_query_object_iv
2807 * - provide LOCAL_GL_SAMPLES_PASSED
2810 void fGetQueryObjectiv(GLuint id
, GLenum pname
, GLint
* params
) {
2812 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv
);
2813 mSymbols
.fGetQueryObjectiv(id
, pname
, params
);
2818 // -----------------------------------------------------------------------------
2819 // GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
2821 void fBindBufferBase(GLenum target
, GLuint index
, GLuint buffer
) {
2823 ASSERT_SYMBOL_PRESENT(fBindBufferBase
);
2824 mSymbols
.fBindBufferBase(target
, index
, buffer
);
2828 void fBindBufferRange(GLenum target
, GLuint index
, GLuint buffer
,
2829 GLintptr offset
, GLsizeiptr size
) {
2831 ASSERT_SYMBOL_PRESENT(fBindBufferRange
);
2832 mSymbols
.fBindBufferRange(target
, index
, buffer
, offset
, size
);
2836 void fGenTransformFeedbacks(GLsizei n
, GLuint
* ids
) {
2838 ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks
);
2839 mSymbols
.fGenTransformFeedbacks(n
, ids
);
2844 void fDeleteTransformFeedbacks(GLsizei n
, const GLuint
* ids
) {
2846 ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks
);
2847 mSymbols
.fDeleteTransformFeedbacks(n
, ids
);
2851 realGLboolean
fIsTransformFeedback(GLuint id
) {
2852 realGLboolean result
= false;
2854 ASSERT_SYMBOL_PRESENT(fIsTransformFeedback
);
2855 result
= mSymbols
.fIsTransformFeedback(id
);
2861 void fBindTransformFeedback(GLenum target
, GLuint id
) {
2863 ASSERT_SYMBOL_PRESENT(fBindTransformFeedback
);
2864 mSymbols
.fBindTransformFeedback(target
, id
);
2868 void fBeginTransformFeedback(GLenum primitiveMode
) {
2870 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback
);
2871 mSymbols
.fBeginTransformFeedback(primitiveMode
);
2875 void fEndTransformFeedback() {
2877 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback
);
2878 mSymbols
.fEndTransformFeedback();
2882 void fTransformFeedbackVaryings(GLuint program
, GLsizei count
,
2883 const GLchar
* const* varyings
,
2884 GLenum bufferMode
) {
2886 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings
);
2887 mSymbols
.fTransformFeedbackVaryings(program
, count
, varyings
, bufferMode
);
2891 void fGetTransformFeedbackVarying(GLuint program
, GLuint index
,
2892 GLsizei bufSize
, GLsizei
* length
,
2893 GLsizei
* size
, GLenum
* type
, GLchar
* name
) {
2895 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying
);
2896 mSymbols
.fGetTransformFeedbackVarying(program
, index
, bufSize
, length
, size
,
2902 void fPauseTransformFeedback() {
2904 ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback
);
2905 mSymbols
.fPauseTransformFeedback();
2909 void fResumeTransformFeedback() {
2911 ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback
);
2912 mSymbols
.fResumeTransformFeedback();
2916 void fGetIntegeri_v(GLenum param
, GLuint index
, GLint
* values
) {
2918 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v
);
2919 mSymbols
.fGetIntegeri_v(param
, index
, values
);
2924 void fGetInteger64i_v(GLenum target
, GLuint index
, GLint64
* data
) {
2925 ASSERT_SYMBOL_PRESENT(fGetInteger64i_v
);
2927 mSymbols
.fGetInteger64i_v(target
, index
, data
);
2932 // -----------------------------------------------------------------------------
2933 // Package XXX_vertex_array_object
2935 void fBindVertexArray(GLuint array
) {
2937 ASSERT_SYMBOL_PRESENT(fBindVertexArray
);
2938 mSymbols
.fBindVertexArray(array
);
2942 void fDeleteVertexArrays(GLsizei n
, const GLuint
* arrays
) {
2944 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays
);
2945 mSymbols
.fDeleteVertexArrays(n
, arrays
);
2949 void fGenVertexArrays(GLsizei n
, GLuint
* arrays
) {
2951 ASSERT_SYMBOL_PRESENT(fGenVertexArrays
);
2952 mSymbols
.fGenVertexArrays(n
, arrays
);
2956 realGLboolean
fIsVertexArray(GLuint array
) {
2957 realGLboolean ret
= false;
2959 ASSERT_SYMBOL_PRESENT(fIsVertexArray
);
2960 ret
= mSymbols
.fIsVertexArray(array
);
2966 // -----------------------------------------------------------------------------
2967 // Extension NV_fence
2969 void fGenFences(GLsizei n
, GLuint
* fences
) {
2970 ASSERT_SYMBOL_PRESENT(fGenFences
);
2972 mSymbols
.fGenFences(n
, fences
);
2976 void fDeleteFences(GLsizei n
, const GLuint
* fences
) {
2977 ASSERT_SYMBOL_PRESENT(fDeleteFences
);
2979 mSymbols
.fDeleteFences(n
, fences
);
2983 void fSetFence(GLuint fence
, GLenum condition
) {
2984 ASSERT_SYMBOL_PRESENT(fSetFence
);
2986 mSymbols
.fSetFence(fence
, condition
);
2990 realGLboolean
fTestFence(GLuint fence
) {
2991 realGLboolean ret
= false;
2992 ASSERT_SYMBOL_PRESENT(fTestFence
);
2994 ret
= mSymbols
.fTestFence(fence
);
3000 void fFinishFence(GLuint fence
) {
3001 ASSERT_SYMBOL_PRESENT(fFinishFence
);
3003 mSymbols
.fFinishFence(fence
);
3008 realGLboolean
fIsFence(GLuint fence
) {
3009 realGLboolean ret
= false;
3010 ASSERT_SYMBOL_PRESENT(fIsFence
);
3012 ret
= mSymbols
.fIsFence(fence
);
3018 void fGetFenceiv(GLuint fence
, GLenum pname
, GLint
* params
) {
3019 ASSERT_SYMBOL_PRESENT(fGetFenceiv
);
3021 mSymbols
.fGetFenceiv(fence
, pname
, params
);
3026 // -----------------------------------------------------------------------------
3027 // Extension NV_texture_barrier
3029 void fTextureBarrier() {
3030 ASSERT_SYMBOL_PRESENT(fTextureBarrier
);
3032 mSymbols
.fTextureBarrier();
3036 // Core GL & Extension ARB_copy_buffer
3038 void fCopyBufferSubData(GLenum readtarget
, GLenum writetarget
,
3039 GLintptr readoffset
, GLintptr writeoffset
,
3042 ASSERT_SYMBOL_PRESENT(fCopyBufferSubData
);
3043 mSymbols
.fCopyBufferSubData(readtarget
, writetarget
, readoffset
,
3048 // -----------------------------------------------------------------------------
3049 // Core GL & Extension ARB_map_buffer_range
3051 void* fMapBufferRange(GLenum target
, GLintptr offset
, GLsizeiptr length
,
3052 GLbitfield access
) {
3053 void* data
= nullptr;
3054 ASSERT_SYMBOL_PRESENT(fMapBufferRange
);
3056 data
= mSymbols
.fMapBufferRange(target
, offset
, length
, access
);
3062 void fFlushMappedBufferRange(GLenum target
, GLintptr offset
,
3063 GLsizeiptr length
) {
3064 ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange
);
3066 mSymbols
.fFlushMappedBufferRange(target
, offset
, length
);
3070 // -----------------------------------------------------------------------------
3071 // Core GL & Extension ARB_sampler_objects
3073 void fGenSamplers(GLsizei count
, GLuint
* samplers
) {
3075 ASSERT_SYMBOL_PRESENT(fGenSamplers
);
3076 mSymbols
.fGenSamplers(count
, samplers
);
3080 void fDeleteSamplers(GLsizei count
, const GLuint
* samplers
) {
3082 ASSERT_SYMBOL_PRESENT(fDeleteSamplers
);
3083 mSymbols
.fDeleteSamplers(count
, samplers
);
3087 realGLboolean
fIsSampler(GLuint sampler
) {
3088 realGLboolean result
= false;
3090 ASSERT_SYMBOL_PRESENT(fIsSampler
);
3091 result
= mSymbols
.fIsSampler(sampler
);
3097 void fBindSampler(GLuint unit
, GLuint sampler
) {
3099 ASSERT_SYMBOL_PRESENT(fBindSampler
);
3100 mSymbols
.fBindSampler(unit
, sampler
);
3104 void fSamplerParameteri(GLuint sampler
, GLenum pname
, GLint param
) {
3106 ASSERT_SYMBOL_PRESENT(fSamplerParameteri
);
3107 mSymbols
.fSamplerParameteri(sampler
, pname
, param
);
3111 void fSamplerParameteriv(GLuint sampler
, GLenum pname
, const GLint
* param
) {
3113 ASSERT_SYMBOL_PRESENT(fSamplerParameteriv
);
3114 mSymbols
.fSamplerParameteriv(sampler
, pname
, param
);
3118 void fSamplerParameterf(GLuint sampler
, GLenum pname
, GLfloat param
) {
3120 ASSERT_SYMBOL_PRESENT(fSamplerParameterf
);
3121 mSymbols
.fSamplerParameterf(sampler
, pname
, param
);
3125 void fSamplerParameterfv(GLuint sampler
, GLenum pname
, const GLfloat
* param
) {
3127 ASSERT_SYMBOL_PRESENT(fSamplerParameterfv
);
3128 mSymbols
.fSamplerParameterfv(sampler
, pname
, param
);
3132 void fGetSamplerParameteriv(GLuint sampler
, GLenum pname
, GLint
* params
) {
3134 ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv
);
3135 mSymbols
.fGetSamplerParameteriv(sampler
, pname
, params
);
3139 void fGetSamplerParameterfv(GLuint sampler
, GLenum pname
, GLfloat
* params
) {
3141 ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv
);
3142 mSymbols
.fGetSamplerParameterfv(sampler
, pname
, params
);
3146 // -----------------------------------------------------------------------------
3147 // Core GL & Extension ARB_uniform_buffer_object
3149 void fGetUniformIndices(GLuint program
, GLsizei uniformCount
,
3150 const GLchar
* const* uniformNames
,
3151 GLuint
* uniformIndices
) {
3152 ASSERT_SYMBOL_PRESENT(fGetUniformIndices
);
3154 mSymbols
.fGetUniformIndices(program
, uniformCount
, uniformNames
,
3160 void fGetActiveUniformsiv(GLuint program
, GLsizei uniformCount
,
3161 const GLuint
* uniformIndices
, GLenum pname
,
3163 ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv
);
3165 mSymbols
.fGetActiveUniformsiv(program
, uniformCount
, uniformIndices
, pname
,
3171 GLuint
fGetUniformBlockIndex(GLuint program
, const GLchar
* uniformBlockName
) {
3173 ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex
);
3175 result
= mSymbols
.fGetUniformBlockIndex(program
, uniformBlockName
);
3181 void fGetActiveUniformBlockiv(GLuint program
, GLuint uniformBlockIndex
,
3182 GLenum pname
, GLint
* params
) {
3183 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv
);
3185 mSymbols
.fGetActiveUniformBlockiv(program
, uniformBlockIndex
, pname
,
3191 void fGetActiveUniformBlockName(GLuint program
, GLuint uniformBlockIndex
,
3192 GLsizei bufSize
, GLsizei
* length
,
3193 GLchar
* uniformBlockName
) {
3194 ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName
);
3196 mSymbols
.fGetActiveUniformBlockName(program
, uniformBlockIndex
, bufSize
,
3197 length
, uniformBlockName
);
3202 void fUniformBlockBinding(GLuint program
, GLuint uniformBlockIndex
,
3203 GLuint uniformBlockBinding
) {
3204 ASSERT_SYMBOL_PRESENT(fUniformBlockBinding
);
3206 mSymbols
.fUniformBlockBinding(program
, uniformBlockIndex
,
3207 uniformBlockBinding
);
3211 // -----------------------------------------------------------------------------
3212 // Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
3213 void fTexStorage2D(GLenum target
, GLsizei levels
, GLenum internalformat
,
3214 GLsizei width
, GLsizei height
) {
3216 ASSERT_SYMBOL_PRESENT(fTexStorage2D
);
3217 mSymbols
.fTexStorage2D(target
, levels
, internalformat
, width
, height
);
3222 void fTexStorage3D(GLenum target
, GLsizei levels
, GLenum internalformat
,
3223 GLsizei width
, GLsizei height
, GLsizei depth
) {
3225 ASSERT_SYMBOL_PRESENT(fTexStorage3D
);
3226 mSymbols
.fTexStorage3D(target
, levels
, internalformat
, width
, height
,
3232 // -----------------------------------------------------------------------------
3234 void fTexImage3D(GLenum target
, GLint level
, GLint internalFormat
,
3235 GLsizei width
, GLsizei height
, GLsizei depth
, GLint border
,
3236 GLenum format
, GLenum type
, const GLvoid
* data
) {
3238 ASSERT_SYMBOL_PRESENT(fTexImage3D
);
3239 mSymbols
.fTexImage3D(target
, level
, internalFormat
, width
, height
, depth
,
3240 border
, format
, type
, data
);
3245 void fTexSubImage3D(GLenum target
, GLint level
, GLint xoffset
, GLint yoffset
,
3246 GLint zoffset
, GLsizei width
, GLsizei height
,
3247 GLsizei depth
, GLenum format
, GLenum type
,
3248 const GLvoid
* pixels
) {
3250 ASSERT_SYMBOL_PRESENT(fTexSubImage3D
);
3251 mSymbols
.fTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
, width
,
3252 height
, depth
, format
, type
, pixels
);
3257 void fCopyTexSubImage3D(GLenum target
, GLint level
, GLint xoffset
,
3258 GLint yoffset
, GLint zoffset
, GLint x
, GLint y
,
3259 GLsizei width
, GLsizei height
) {
3262 ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D
);
3263 mSymbols
.fCopyTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
, x
, y
,
3269 void fCompressedTexImage3D(GLenum target
, GLint level
, GLenum internalformat
,
3270 GLsizei width
, GLsizei height
, GLsizei depth
,
3271 GLint border
, GLsizei imageSize
,
3272 const GLvoid
* data
) {
3274 ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D
);
3275 mSymbols
.fCompressedTexImage3D(target
, level
, internalformat
, width
, height
,
3276 depth
, border
, imageSize
, data
);
3280 void fCompressedTexSubImage3D(GLenum target
, GLint level
, GLint xoffset
,
3281 GLint yoffset
, GLint zoffset
, GLsizei width
,
3282 GLsizei height
, GLsizei depth
, GLenum format
,
3283 GLsizei imageSize
, const GLvoid
* data
) {
3285 ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D
);
3286 mSymbols
.fCompressedTexSubImage3D(target
, level
, xoffset
, yoffset
, zoffset
,
3287 width
, height
, depth
, format
, imageSize
,
3292 // -----------------------------------------------------------------------------
3295 const GLubyte
* fGetStringi(GLenum name
, GLuint index
) {
3296 const GLubyte
* ret
= nullptr;
3298 ASSERT_SYMBOL_PRESENT(fGetStringi
);
3299 ret
= mSymbols
.fGetStringi(name
, index
);
3305 // -----------------------------------------------------------------------------
3306 // APPLE_framebuffer_multisample
3308 void fResolveMultisampleFramebufferAPPLE() {
3310 ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE
);
3311 mSymbols
.fResolveMultisampleFramebufferAPPLE();
3315 // -----------------------------------------------------------------------------
3318 void fFinishObjectAPPLE(GLenum object
, GLint name
) {
3320 ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE
);
3321 mSymbols
.fFinishObjectAPPLE(object
, name
);
3325 realGLboolean
fTestObjectAPPLE(GLenum object
, GLint name
) {
3326 realGLboolean ret
= false;
3328 ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE
);
3329 ret
= mSymbols
.fTestObjectAPPLE(object
, name
);
3334 // -----------------------------------------------------------------------------
3337 void fPrimitiveRestartIndex(GLuint index
) {
3339 ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex
);
3340 mSymbols
.fPrimitiveRestartIndex(index
);
3344 // -----------------------------------------------------------------------------
3347 void fFramebufferTextureMultiview(GLenum target
, GLenum attachment
,
3348 GLuint texture
, GLint level
,
3349 GLint baseViewIndex
,
3350 GLsizei numViews
) const {
3352 ASSERT_SYMBOL_PRESENT(fFramebufferTextureMultiview
);
3353 mSymbols
.fFramebufferTextureMultiview(target
, attachment
, texture
, level
,
3354 baseViewIndex
, numViews
);
3359 // draw_buffers_indexed
3361 void fBlendEquationSeparatei(GLuint i
, GLenum modeRGB
,
3362 GLenum modeAlpha
) const {
3364 mSymbols
.fBlendEquationSeparatei(i
, modeRGB
, modeAlpha
);
3368 void fBlendFuncSeparatei(GLuint i
, GLenum sfactorRGB
, GLenum dfactorRGB
,
3369 GLenum sfactorAlpha
, GLenum dfactorAlpha
) const {
3371 mSymbols
.fBlendFuncSeparatei(i
, sfactorRGB
, dfactorRGB
, sfactorAlpha
,
3376 void fColorMaski(GLuint i
, realGLboolean red
, realGLboolean green
,
3377 realGLboolean blue
, realGLboolean alpha
) const {
3379 mSymbols
.fColorMaski(i
, red
, green
, blue
, alpha
);
3383 void fDisablei(GLenum capability
, GLuint i
) const {
3385 mSymbols
.fDisablei(capability
, i
);
3389 void fEnablei(GLenum capability
, GLuint i
) const {
3391 mSymbols
.fEnablei(capability
, i
);
3397 void fProvokingVertex(GLenum mode
) const {
3399 mSymbols
.fProvokingVertex(mode
);
3405 #undef BEFORE_GL_CALL
3406 #undef AFTER_GL_CALL
3407 #undef ASSERT_SYMBOL_PRESENT
3408 // #undef TRACKING_CONTEXT // Needed in GLContext.cpp
3409 #undef ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL
3411 // -----------------------------------------------------------------------------
3414 explicit GLContext(const GLContextDesc
&, GLContext
* sharedContext
= nullptr,
3415 bool canUseTLSIsCurrent
= false);
3417 // -----------------------------------------------------------------------------
3420 virtual ~GLContext();
3422 // Mark this context as destroyed. This will nullptr out all
3423 // the GL function pointers!
3424 void MarkDestroyed();
3427 virtual void OnMarkDestroyed() {}
3429 // -----------------------------------------------------------------------------
3430 // Everything that isn't standard GL APIs
3432 typedef gfx::SurfaceFormat SurfaceFormat
;
3435 virtual void ReleaseSurface() {}
3437 bool IsDestroyed() const {
3438 // MarkDestroyed will mark all these as null.
3439 return mContextLost
&& mSymbols
.fUseProgram
== nullptr;
3442 GLContext
* GetSharedContext() { return mSharedContext
; }
3445 * Returns true if the thread on which this context was created is the
3446 * currently executing thread.
3448 bool IsValidOwningThread() const;
3450 static void PlatformStartup();
3454 * If this context wraps a double-buffered target, swap the back
3455 * and front buffers. It should be assumed that after a swap, the
3456 * contents of the new back buffer are undefined.
3458 virtual bool SwapBuffers() { return false; }
3461 * Stores a damage region (in origin bottom left coordinates), which
3462 * makes the next SwapBuffers call do eglSwapBuffersWithDamage if supported.
3464 * Note that even if only part of the context is damaged, the entire buffer
3465 * needs to be filled with up-to-date contents. This region is only a hint
3466 * telling the system compositor which parts of the buffer were updated.
3468 virtual void SetDamage(const nsIntRegion
& aDamageRegion
) {}
3471 * Get the buffer age. If it returns 0, that indicates the buffer state is
3472 * unknown and the entire frame should be redrawn.
3474 virtual GLint
GetBufferAge() const { return 0; }
3477 * Defines a two-dimensional texture image for context target surface
3479 virtual bool BindTexImage() { return false; }
3481 * Releases a color buffer that is being used as a texture
3483 virtual bool ReleaseTexImage() { return false; }
3485 virtual Maybe
<SymbolLoader
> GetSymbolLoader() const = 0;
3487 void BindFB(GLuint fb
) {
3488 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER
, fb
);
3489 MOZ_GL_ASSERT(this, !fb
|| fIsFramebuffer(fb
));
3492 void BindDrawFB(GLuint fb
) {
3493 fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT
, fb
);
3496 void BindReadFB(GLuint fb
) {
3497 fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT
, fb
);
3500 GLuint
GetDrawFB() const {
3501 return GetIntAs
<GLuint
>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT
);
3504 GLuint
GetReadFB() const {
3505 auto bindEnum
= LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
;
3506 if (!IsSupported(GLFeature::split_framebuffer
)) {
3507 bindEnum
= LOCAL_GL_FRAMEBUFFER_BINDING
;
3509 return GetIntAs
<GLuint
>(bindEnum
);
3512 GLuint
GetFB() const {
3513 const auto ret
= GetDrawFB();
3514 MOZ_ASSERT(ret
== GetReadFB());
3519 void GetShaderPrecisionFormatNonES2(GLenum shadertype
, GLenum precisiontype
,
3520 GLint
* range
, GLint
* precision
) {
3521 switch (precisiontype
) {
3522 case LOCAL_GL_LOW_FLOAT
:
3523 case LOCAL_GL_MEDIUM_FLOAT
:
3524 case LOCAL_GL_HIGH_FLOAT
:
3525 // Assume IEEE 754 precision
3530 case LOCAL_GL_LOW_INT
:
3531 case LOCAL_GL_MEDIUM_INT
:
3532 case LOCAL_GL_HIGH_INT
:
3533 // Some (most) hardware only supports single-precision floating-point
3534 // numbers, which can accurately represent integers up to +/-16777216
3543 virtual GLenum
GetPreferredARGB32Format() const { return LOCAL_GL_RGBA
; }
3545 virtual GLenum
GetPreferredEGLImageTextureTarget() const {
3546 #ifdef MOZ_WIDGET_GTK
3547 return LOCAL_GL_TEXTURE_2D
;
3549 return IsExtensionSupported(OES_EGL_image_external
)
3550 ? LOCAL_GL_TEXTURE_EXTERNAL
3551 : LOCAL_GL_TEXTURE_2D
;
3555 virtual bool RenewSurface(widget::CompositorWidget
* aWidget
) { return false; }
3557 // Shared code for GL extensions and GLX extensions.
3558 static bool ListHasExtension(const GLubyte
* extensions
,
3559 const char* extension
);
3563 DebugFlagEnabled
= 1 << 0,
3564 DebugFlagTrace
= 1 << 1,
3565 DebugFlagAbortOnError
= 1 << 2
3568 const uint8_t mDebugFlags
;
3569 static uint8_t ChooseDebugFlags(CreateContextFlags createFlags
);
3572 RefPtr
<GLContext
> mSharedContext
;
3575 // The thread id which this context was created.
3576 Maybe
<PlatformThreadId
> mOwningThreadId
;
3579 GLContextSymbols mSymbols
= {};
3581 UniquePtr
<GLBlitHelper
> mBlitHelper
;
3582 UniquePtr
<GLReadTexImageHelper
> mReadTexImageHelper
;
3585 GLBlitHelper
* BlitHelper();
3586 GLReadTexImageHelper
* ReadTexImageHelper();
3588 // Assumes shares are created by all sharing with the same global context.
3589 bool SharesWith(const GLContext
* other
) const {
3590 MOZ_ASSERT(!this->mSharedContext
|| !this->mSharedContext
->mSharedContext
);
3591 MOZ_ASSERT(!other
->mSharedContext
||
3592 !other
->mSharedContext
->mSharedContext
);
3593 MOZ_ASSERT(!this->mSharedContext
|| !other
->mSharedContext
||
3594 this->mSharedContext
== other
->mSharedContext
);
3596 const GLContext
* thisShared
=
3597 this->mSharedContext
? this->mSharedContext
: this;
3598 const GLContext
* otherShared
=
3599 other
->mSharedContext
? other
->mSharedContext
: other
;
3601 return thisShared
== otherShared
;
3604 bool IsFramebufferComplete(GLuint fb
, GLenum
* status
= nullptr);
3606 // Does not check completeness.
3607 void AttachBuffersToFB(GLuint colorTex
, GLuint colorRB
, GLuint depthRB
,
3608 GLuint stencilRB
, GLuint fb
,
3609 GLenum target
= LOCAL_GL_TEXTURE_2D
);
3611 // Passing null is fine if the value you'd get is 0.
3612 bool AssembleOffscreenFBs(const GLuint colorMSRB
, const GLuint depthRB
,
3613 const GLuint stencilRB
, const GLuint texture
,
3614 GLuint
* drawFB
, GLuint
* readFB
);
3617 SharedSurface
* mLockedSurface
= nullptr;
3620 void LockSurface(SharedSurface
* surf
) { mLockedSurface
= surf
; }
3622 void UnlockSurface(SharedSurface
* surf
) {
3623 MOZ_ASSERT(mLockedSurface
== surf
);
3624 mLockedSurface
= nullptr;
3627 SharedSurface
* GetLockedSurface() const { return mLockedSurface
; }
3629 bool IsOffscreen() const { return mDesc
.isOffscreen
; }
3631 bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs
; }
3633 bool IsOffscreenSizeAllowed(const gfx::IntSize
& aSize
) const;
3635 virtual bool Init();
3639 void LoadMoreSymbols(const SymbolLoader
& loader
);
3640 bool LoadExtSymbols(const SymbolLoader
& loader
, const SymLoadStruct
* list
,
3642 bool LoadFeatureSymbols(const SymbolLoader
& loader
, const SymLoadStruct
* list
,
3646 void InitExtensions();
3648 GLint mViewportRect
[4] = {};
3649 GLint mScissorRect
[4] = {};
3651 uint32_t mMaxTexOrRbSize
= 0;
3652 GLint mMaxTextureSize
= 0;
3653 GLint mMaxCubeMapTextureSize
= 0;
3654 GLint mMaxRenderbufferSize
= 0;
3655 GLint mMaxViewportDims
[2] = {};
3656 GLsizei mMaxSamples
= 0;
3657 bool mNeedsTextureSizeChecks
= false;
3658 bool mNeedsFlushBeforeDeleteFB
= false;
3659 bool mTextureAllocCrashesOnMapFailure
= false;
3660 bool mNeedsCheckAfterAttachTextureToFb
= false;
3661 const bool mWorkAroundDriverBugs
;
3662 mutable uint64_t mSyncGLCallCount
= 0;
3664 bool IsTextureSizeSafeToPassToDriver(GLenum target
, GLsizei width
,
3665 GLsizei height
) const {
3666 if (mNeedsTextureSizeChecks
) {
3667 // some drivers incorrectly handle some large texture sizes that are below
3668 // the max texture size that they report. So we check ourselves against
3669 // our own values (mMax[CubeMap]TextureSize). see bug 737182 for Mac Intel
3670 // 2D textures see bug 684882 for Mac Intel cube map textures see bug
3671 // 814716 for Mesa Nouveau
3673 target
== LOCAL_GL_TEXTURE_CUBE_MAP
||
3674 (target
>= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X
&&
3675 target
<= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
)
3676 ? mMaxCubeMapTextureSize
3678 return width
<= maxSize
&& height
<= maxSize
;
3684 auto MaxSamples() const { return uint32_t(mMaxSamples
); }
3685 auto MaxTextureSize() const { return uint32_t(mMaxTextureSize
); }
3686 auto MaxRenderbufferSize() const { return uint32_t(mMaxRenderbufferSize
); }
3687 auto MaxTexOrRbSize() const { return mMaxTexOrRbSize
; }
3689 #ifdef MOZ_GL_DEBUG_BUILD
3690 void CreatedProgram(GLContext
* aOrigin
, GLuint aName
);
3691 void CreatedShader(GLContext
* aOrigin
, GLuint aName
);
3692 void CreatedBuffers(GLContext
* aOrigin
, GLsizei aCount
, GLuint
* aNames
);
3693 void CreatedQueries(GLContext
* aOrigin
, GLsizei aCount
, GLuint
* aNames
);
3694 void CreatedTextures(GLContext
* aOrigin
, GLsizei aCount
, GLuint
* aNames
);
3695 void CreatedFramebuffers(GLContext
* aOrigin
, GLsizei aCount
, GLuint
* aNames
);
3696 void CreatedRenderbuffers(GLContext
* aOrigin
, GLsizei aCount
, GLuint
* aNames
);
3697 void DeletedProgram(GLContext
* aOrigin
, GLuint aName
);
3698 void DeletedShader(GLContext
* aOrigin
, GLuint aName
);
3699 void DeletedBuffers(GLContext
* aOrigin
, GLsizei aCount
, const GLuint
* aNames
);
3700 void DeletedQueries(GLContext
* aOrigin
, GLsizei aCount
, const GLuint
* aNames
);
3701 void DeletedTextures(GLContext
* aOrigin
, GLsizei aCount
,
3702 const GLuint
* aNames
);
3703 void DeletedFramebuffers(GLContext
* aOrigin
, GLsizei aCount
,
3704 const GLuint
* aNames
);
3705 void DeletedRenderbuffers(GLContext
* aOrigin
, GLsizei aCount
,
3706 const GLuint
* aNames
);
3708 void SharedContextDestroyed(GLContext
* aChild
);
3709 void ReportOutstandingNames();
3711 struct NamedResource
{
3712 NamedResource() : origin(nullptr), name(0), originDeleted(false) {}
3714 NamedResource(GLContext
* aOrigin
, GLuint aName
)
3715 : origin(aOrigin
), name(aName
), originDeleted(false) {}
3722 bool operator<(const NamedResource
& aOther
) const {
3723 if (intptr_t(origin
) < intptr_t(aOther
.origin
)) return true;
3724 if (name
< aOther
.name
) return true;
3727 bool operator==(const NamedResource
& aOther
) const {
3728 return origin
== aOther
.origin
&& name
== aOther
.name
&&
3729 originDeleted
== aOther
.originDeleted
;
3733 nsTArray
<NamedResource
> mTrackedPrograms
;
3734 nsTArray
<NamedResource
> mTrackedShaders
;
3735 nsTArray
<NamedResource
> mTrackedTextures
;
3736 nsTArray
<NamedResource
> mTrackedFramebuffers
;
3737 nsTArray
<NamedResource
> mTrackedRenderbuffers
;
3738 nsTArray
<NamedResource
> mTrackedBuffers
;
3739 nsTArray
<NamedResource
> mTrackedQueries
;
3743 bool mHeavyGLCallsSinceLastFlush
= false;
3746 void FlushIfHeavyGLCallsSinceLastFlush();
3747 static bool ShouldSpew();
3748 static bool ShouldDumpExts();
3752 void TexParams_SetClampNoMips(GLenum target
= LOCAL_GL_TEXTURE_2D
) {
3753 fTexParameteri(target
, LOCAL_GL_TEXTURE_WRAP_S
, LOCAL_GL_CLAMP_TO_EDGE
);
3754 fTexParameteri(target
, LOCAL_GL_TEXTURE_WRAP_T
, LOCAL_GL_CLAMP_TO_EDGE
);
3755 fTexParameteri(target
, LOCAL_GL_TEXTURE_MAG_FILTER
, LOCAL_GL_NEAREST
);
3756 fTexParameteri(target
, LOCAL_GL_TEXTURE_MIN_FILTER
, LOCAL_GL_NEAREST
);
3761 GLuint
CreateFramebuffer() {
3763 fGenFramebuffers(1, &x
);
3766 GLuint
CreateRenderbuffer() {
3768 fGenRenderbuffers(1, &x
);
3771 GLuint
CreateTexture() {
3773 fGenTextures(1, &x
);
3777 void DeleteFramebuffer(const GLuint x
) { fDeleteFramebuffers(1, &x
); }
3778 void DeleteRenderbuffer(const GLuint x
) { fDeleteRenderbuffers(1, &x
); }
3779 void DeleteTexture(const GLuint x
) { fDeleteTextures(1, &x
); }
3782 bool DoesStringMatch(const char* aString
, const char* aWantedString
);
3784 void SplitByChar(const nsACString
& str
, const char delim
,
3785 std::vector
<nsCString
>* const out
);
3788 bool MarkBitfieldByString(const nsACString
& str
,
3789 const char* const (&markStrList
)[N
],
3790 std::bitset
<N
>* const out_markList
) {
3791 for (size_t i
= 0; i
< N
; i
++) {
3792 if (str
.Equals(markStrList
[i
])) {
3793 (*out_markList
)[i
] = 1;
3801 void MarkBitfieldByStrings(const std::vector
<nsCString
>& strList
,
3803 const char* const (&markStrList
)[N
],
3804 std::bitset
<N
>* const out_markList
) {
3805 for (auto itr
= strList
.begin(); itr
!= strList
.end(); ++itr
) {
3806 const nsACString
& str
= *itr
;
3807 const bool wasMarked
= MarkBitfieldByString(str
, markStrList
, out_markList
);
3809 printf_stderr(" %s%s\n", str
.BeginReading(), wasMarked
? "(*)" : "");
3815 class Renderbuffer final
{
3817 const WeakPtr
<GLContext
> weakGl
;
3821 static GLuint
Create(GLContext
& gl
) {
3823 gl
.fGenRenderbuffers(1, &ret
);
3828 explicit Renderbuffer(GLContext
& gl
) : weakGl(&gl
), name(Create(gl
)) {}
3831 const RefPtr
<GLContext
> gl
= weakGl
.get();
3832 if (!gl
|| !gl
->MakeCurrent()) return;
3833 gl
->fDeleteRenderbuffers(1, &name
);
3839 class Texture final
{
3841 const WeakPtr
<GLContext
> weakGl
;
3845 static GLuint
Create(GLContext
& gl
) {
3847 gl
.fGenTextures(1, &ret
);
3852 explicit Texture(GLContext
& gl
) : weakGl(&gl
), name(Create(gl
)) {}
3855 const RefPtr
<GLContext
> gl
= weakGl
.get();
3856 if (!gl
|| !gl
->MakeCurrent()) return;
3857 gl
->fDeleteTextures(1, &name
);
3862 * Helper function that creates a 2D texture aSize.width x aSize.height with
3863 * storage type specified by aFormats. Returns GL texture object id.
3865 * See mozilla::gl::CreateTexture.
3867 UniquePtr
<Texture
> CreateTexture(GLContext
&, const gfx::IntSize
& size
);
3870 * Helper function that calculates the number of bytes required per
3871 * texel for a texture from its format and type.
3873 uint32_t GetBytesPerTexel(GLenum format
, GLenum type
);
3875 void MesaMemoryLeakWorkaround();
3877 } /* namespace gl */
3878 } /* namespace mozilla */
3880 #endif /* GLCONTEXT_H_ */