Bumping manifests a=b2g-bump
[gecko.git] / gfx / gl / GLContext.h
blob5f811942d870e63595952db52cf19d9c802e1ed6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef GLCONTEXT_H_
8 #define GLCONTEXT_H_
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <ctype.h>
13 #include <map>
14 #include <bitset>
15 #include <queue>
17 #ifdef DEBUG
18 #include <string.h>
19 #endif
21 #ifdef WIN32
22 #include <windows.h>
23 #endif
25 #ifdef GetClassName
26 #undef GetClassName
27 #endif
29 #include "mozilla/UniquePtr.h"
31 #include "GLDefs.h"
32 #include "GLLibraryLoader.h"
33 #include "nsISupportsImpl.h"
34 #include "plstr.h"
35 #include "nsDataHashtable.h"
36 #include "nsHashKeys.h"
37 #include "nsAutoPtr.h"
38 #include "GLContextTypes.h"
39 #include "GLTextureImage.h"
40 #include "SurfaceTypes.h"
41 #include "GLScreenBuffer.h"
42 #include "GLContextSymbols.h"
43 #include "base/platform_thread.h" // for PlatformThreadId
44 #include "mozilla/GenericRefCounted.h"
45 #include "gfx2DGlue.h"
47 class nsIntRegion;
48 class nsIRunnable;
49 class nsIThread;
51 namespace android {
52 class GraphicBuffer;
55 namespace mozilla {
56 namespace gfx {
57 class DataSourceSurface;
58 class SourceSurface;
61 namespace gl {
62 class GLContext;
63 class GLLibraryEGL;
64 class GLScreenBuffer;
65 class TextureGarbageBin;
66 class GLBlitHelper;
67 class GLBlitTextureImageHelper;
68 class GLReadTexImageHelper;
69 struct SurfaceCaps;
72 namespace layers {
73 class ColorTextureLayerProgram;
77 namespace mozilla {
78 namespace gl {
80 MOZ_BEGIN_ENUM_CLASS(GLFeature)
81 bind_buffer_offset,
82 blend_minmax,
83 depth_texture,
84 draw_buffers,
85 draw_instanced,
86 draw_range_elements,
87 element_index_uint,
88 ES2_compatibility,
89 ES3_compatibility,
90 frag_color_float,
91 frag_depth,
92 framebuffer_blit,
93 framebuffer_multisample,
94 framebuffer_object,
95 get_query_object_iv,
96 instanced_arrays,
97 instanced_non_arrays,
98 occlusion_query,
99 occlusion_query_boolean,
100 occlusion_query2,
101 packed_depth_stencil,
102 query_objects,
103 renderbuffer_color_float,
104 renderbuffer_color_half_float,
105 robustness,
106 sRGB,
107 standard_derivatives,
108 texture_float,
109 texture_float_linear,
110 texture_half_float,
111 texture_half_float_linear,
112 texture_non_power_of_two,
113 transform_feedback,
114 vertex_array_object,
115 EnumMax
116 MOZ_END_ENUM_CLASS(GLFeature)
118 MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
119 Unknown = 0,
120 OpenGL, // only for IsAtLeast's <profile> parameter
121 OpenGLCore,
122 OpenGLCompatibility,
123 OpenGLES
124 MOZ_END_ENUM_CLASS(ContextProfile)
126 MOZ_BEGIN_ENUM_CLASS(GLVendor)
127 Intel,
128 NVIDIA,
129 ATI,
130 Qualcomm,
131 Imagination,
132 Nouveau,
133 Vivante,
134 VMware,
135 Other
136 MOZ_END_ENUM_CLASS(GLVendor)
138 MOZ_BEGIN_ENUM_CLASS(GLRenderer)
139 Adreno200,
140 Adreno205,
141 AdrenoTM200,
142 AdrenoTM205,
143 AdrenoTM320,
144 SGX530,
145 SGX540,
146 Tegra,
147 AndroidEmulator,
148 GalliumLlvmpipe,
149 IntelHD3000,
150 MicrosoftBasicRenderDriver,
151 Other
152 MOZ_END_ENUM_CLASS(GLRenderer)
154 class GLContext
155 : public GLLibraryLoader
156 , public GenericAtomicRefCounted
158 // -----------------------------------------------------------------------------
159 // basic enums
160 public:
162 // -----------------------------------------------------------------------------
163 // basic getters
164 public:
167 * Returns true if the context is using ANGLE. This should only be overridden
168 * for an ANGLE implementation.
170 virtual bool IsANGLE() const {
171 return false;
175 * Return true if we are running on a OpenGL core profile context
177 inline bool IsCoreProfile() const {
178 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
180 return mProfile == ContextProfile::OpenGLCore;
184 * Return true if we are running on a OpenGL compatibility profile context
185 * (legacy profile 2.1 on Max OS X)
187 inline bool IsCompatibilityProfile() const {
188 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
190 return mProfile == ContextProfile::OpenGLCompatibility;
194 * Return true if the context is a true OpenGL ES context or an ANGLE context
196 inline bool IsGLES() const {
197 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
199 return mProfile == ContextProfile::OpenGLES;
202 static const char* GetProfileName(ContextProfile profile)
204 switch (profile)
206 case ContextProfile::OpenGL:
207 return "OpenGL";
208 case ContextProfile::OpenGLCore:
209 return "OpenGL Core";
210 case ContextProfile::OpenGLCompatibility:
211 return "OpenGL Compatibility";
212 case ContextProfile::OpenGLES:
213 return "OpenGL ES";
214 default:
215 break;
218 MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile");
219 return "OpenGL unknown profile";
223 * Return true if we are running on a OpenGL core profile context
225 const char* ProfileString() const {
226 return GetProfileName(mProfile);
230 * Return true if the context is compatible with given parameters
232 * IsAtLeast(ContextProfile::OpenGL, N) is exactly same as
233 * IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N)
235 inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
237 MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad <profile> parameter");
238 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
239 MOZ_ASSERT(mVersion != 0, "unknown context version");
241 if (version > mVersion) {
242 return false;
245 if (profile == ContextProfile::OpenGL) {
246 return profile == ContextProfile::OpenGLCore ||
247 profile == ContextProfile::OpenGLCompatibility;
250 return profile == mProfile;
254 * Return the version of the context.
255 * Example :
256 * If this a OpenGL 2.1, that will return 210
258 inline unsigned int Version() const {
259 return mVersion;
262 const char* VersionString() const {
263 return mVersionString.get();
266 GLVendor Vendor() const {
267 return mVendor;
270 GLRenderer Renderer() const {
271 return mRenderer;
274 bool IsContextLost() const {
275 return mContextLost;
279 * If this context is double-buffered, returns TRUE.
281 virtual bool IsDoubleBuffered() const {
282 return false;
285 virtual GLContextType GetContextType() const = 0;
287 virtual bool IsCurrent() = 0;
289 protected:
291 bool mInitialized;
292 bool mIsOffscreen;
293 bool mIsGlobalSharedContext;
294 bool mContextLost;
297 * mVersion store the OpenGL's version, multiplied by 100. For example, if
298 * the context is an OpenGL 2.1 context, mVersion value will be 210.
300 unsigned int mVersion;
301 nsCString mVersionString;
302 ContextProfile mProfile;
304 GLVendor mVendor;
305 GLRenderer mRenderer;
307 inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
308 MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
309 MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
310 MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
312 mVersion = version;
313 mProfile = profile;
317 // -----------------------------------------------------------------------------
318 // Extensions management
320 * This mechanism is designed to know if an extension is supported. In the long
321 * term, we would like to only use the extension group queries XXX_* to have
322 * full compatibility with context version and profiles (especialy the core that
323 * officialy don't bring any extensions).
325 public:
328 * Known GL extensions that can be queried by
329 * IsExtensionSupported. The results of this are cached, and as
330 * such it's safe to use this even in performance critical code.
331 * If you add to this array, remember to add to the string names
332 * in GLContext.cpp.
334 enum GLExtensions {
335 Extension_None = 0,
336 AMD_compressed_ATC_texture,
337 ANGLE_depth_texture,
338 ANGLE_framebuffer_blit,
339 ANGLE_framebuffer_multisample,
340 ANGLE_instanced_arrays,
341 ANGLE_texture_compression_dxt3,
342 ANGLE_texture_compression_dxt5,
343 APPLE_client_storage,
344 APPLE_texture_range,
345 APPLE_vertex_array_object,
346 ARB_ES2_compatibility,
347 ARB_ES3_compatibility,
348 ARB_color_buffer_float,
349 ARB_depth_texture,
350 ARB_draw_buffers,
351 ARB_draw_instanced,
352 ARB_framebuffer_object,
353 ARB_framebuffer_sRGB,
354 ARB_half_float_pixel,
355 ARB_instanced_arrays,
356 ARB_occlusion_query2,
357 ARB_pixel_buffer_object,
358 ARB_robustness,
359 ARB_sync,
360 ARB_texture_float,
361 ARB_texture_non_power_of_two,
362 ARB_texture_rectangle,
363 ARB_vertex_array_object,
364 EXT_bgra,
365 EXT_blend_minmax,
366 EXT_color_buffer_float,
367 EXT_color_buffer_half_float,
368 EXT_draw_buffers,
369 EXT_draw_instanced,
370 EXT_draw_range_elements,
371 EXT_frag_depth,
372 EXT_framebuffer_blit,
373 EXT_framebuffer_multisample,
374 EXT_framebuffer_object,
375 EXT_framebuffer_sRGB,
376 EXT_gpu_shader4,
377 EXT_occlusion_query_boolean,
378 EXT_packed_depth_stencil,
379 EXT_read_format_bgra,
380 EXT_robustness,
381 EXT_sRGB,
382 EXT_shader_texture_lod,
383 EXT_texture_compression_dxt1,
384 EXT_texture_compression_s3tc,
385 EXT_texture_filter_anisotropic,
386 EXT_texture_format_BGRA8888,
387 EXT_texture_sRGB,
388 EXT_transform_feedback,
389 EXT_unpack_subimage,
390 IMG_read_format,
391 IMG_texture_compression_pvrtc,
392 IMG_texture_npot,
393 KHR_debug,
394 NV_draw_instanced,
395 NV_fence,
396 NV_half_float,
397 NV_instanced_arrays,
398 NV_transform_feedback,
399 OES_EGL_image,
400 OES_EGL_image_external,
401 OES_EGL_sync,
402 OES_compressed_ETC1_RGB8_texture,
403 OES_depth24,
404 OES_depth32,
405 OES_depth_texture,
406 OES_element_index_uint,
407 OES_packed_depth_stencil,
408 OES_rgb8_rgba8,
409 OES_standard_derivatives,
410 OES_stencil8,
411 OES_texture_float,
412 OES_texture_float_linear,
413 OES_texture_half_float,
414 OES_texture_half_float_linear,
415 OES_texture_npot,
416 OES_vertex_array_object,
417 Extensions_Max,
418 Extensions_End
421 bool IsExtensionSupported(GLExtensions aKnownExtension) const {
422 return mAvailableExtensions[aKnownExtension];
425 void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
426 mAvailableExtensions[aKnownExtension] = 0;
429 void MarkExtensionSupported(GLExtensions aKnownExtension) {
430 mAvailableExtensions[aKnownExtension] = 1;
434 public:
436 template<size_t N>
437 static void InitializeExtensionsBitSet(std::bitset<N>& extensionsBitset, const char* extStr, const char** extList, bool verbose = false)
439 char* exts = ::strdup(extStr);
441 if (verbose)
442 printf_stderr("Extensions: %s\n", exts);
444 char* cur = exts;
445 bool done = false;
446 while (!done) {
447 char* space = strchr(cur, ' ');
448 if (space) {
449 *space = '\0';
450 } else {
451 done = true;
454 for (int i = 0; extList[i]; ++i) {
455 if (PL_strcasecmp(cur, extList[i]) == 0) {
456 if (verbose)
457 printf_stderr("Found extension %s\n", cur);
458 extensionsBitset[i] = true;
462 cur = space + 1;
465 free(exts);
469 protected:
470 std::bitset<Extensions_Max> mAvailableExtensions;
473 // -----------------------------------------------------------------------------
474 // Feature queries
476 * This mecahnism introduces a new way to check if a OpenGL feature is
477 * supported, regardless of whether it is supported by an extension or natively
478 * by the context version/profile
480 public:
481 bool IsSupported(GLFeature feature) const {
482 return mAvailableFeatures[size_t(feature)];
485 static const char* GetFeatureName(GLFeature feature);
488 private:
489 std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
492 * Init features regarding OpenGL extension and context version and profile
494 void InitFeatures();
497 * Mark the feature and associated extensions as unsupported
499 void MarkUnsupported(GLFeature feature);
502 * Is this feature supported using the core (unsuffixed) symbols?
504 bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
506 // -----------------------------------------------------------------------------
507 // Robustness handling
508 public:
509 bool HasRobustness() const {
510 return mHasRobustness;
514 * The derived class is expected to provide information on whether or not it
515 * supports robustness.
517 virtual bool SupportsRobustness() const = 0;
519 private:
520 bool mHasRobustness;
522 // -----------------------------------------------------------------------------
523 // Error handling
524 public:
525 static const char* GLErrorToString(GLenum aError) {
526 switch (aError) {
527 case LOCAL_GL_INVALID_ENUM:
528 return "GL_INVALID_ENUM";
529 case LOCAL_GL_INVALID_VALUE:
530 return "GL_INVALID_VALUE";
531 case LOCAL_GL_INVALID_OPERATION:
532 return "GL_INVALID_OPERATION";
533 case LOCAL_GL_STACK_OVERFLOW:
534 return "GL_STACK_OVERFLOW";
535 case LOCAL_GL_STACK_UNDERFLOW:
536 return "GL_STACK_UNDERFLOW";
537 case LOCAL_GL_OUT_OF_MEMORY:
538 return "GL_OUT_OF_MEMORY";
539 case LOCAL_GL_TABLE_TOO_LARGE:
540 return "GL_TABLE_TOO_LARGE";
541 case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
542 return "GL_INVALID_FRAMEBUFFER_OPERATION";
543 default:
544 return "";
548 /** \returns the first GL error, and guarantees that all GL error flags are cleared,
549 * i.e. that a subsequent GetError call will return NO_ERROR
551 GLenum GetAndClearError() {
552 // the first error is what we want to return
553 GLenum error = fGetError();
555 if (error) {
556 // clear all pending errors
557 while(fGetError()) {}
560 return error;
563 private:
564 GLenum raw_fGetError() {
565 return mSymbols.fGetError();
568 std::queue<GLenum> mGLErrorQueue;
570 public:
571 GLenum fGetError() {
572 if (!mGLErrorQueue.empty()) {
573 GLenum err = mGLErrorQueue.front();
574 mGLErrorQueue.pop();
575 return err;
578 return GetUnpushedError();
581 private:
582 GLenum GetUnpushedError() {
583 return raw_fGetError();
586 void ClearUnpushedErrors() {
587 while (GetUnpushedError()) {
588 // Discard errors.
592 GLenum GetAndClearUnpushedErrors() {
593 GLenum err = GetUnpushedError();
594 if (err) {
595 ClearUnpushedErrors();
597 return err;
600 void PushError(GLenum err) {
601 mGLErrorQueue.push(err);
604 void GetAndPushAllErrors() {
605 while (true) {
606 GLenum err = GetUnpushedError();
607 if (!err)
608 break;
610 PushError(err);
614 ////////////////////////////////////
615 // Use this safer option.
616 private:
617 #ifdef DEBUG
618 bool mIsInLocalErrorCheck;
619 #endif
621 public:
622 class ScopedLocalErrorCheck {
623 GLContext* const mGL;
624 bool mHasBeenChecked;
626 public:
627 explicit ScopedLocalErrorCheck(GLContext* gl)
628 : mGL(gl)
629 , mHasBeenChecked(false)
631 #ifdef DEBUG
632 MOZ_ASSERT(!mGL->mIsInLocalErrorCheck);
633 mGL->mIsInLocalErrorCheck = true;
634 #endif
635 mGL->GetAndPushAllErrors();
638 GLenum GetLocalError() {
639 #ifdef DEBUG
640 MOZ_ASSERT(mGL->mIsInLocalErrorCheck);
641 mGL->mIsInLocalErrorCheck = false;
642 #endif
644 MOZ_ASSERT(!mHasBeenChecked);
645 mHasBeenChecked = true;
647 return mGL->GetAndClearUnpushedErrors();
650 ~ScopedLocalErrorCheck() {
651 MOZ_ASSERT(mHasBeenChecked);
655 private:
656 static void GLAPIENTRY StaticDebugCallback(GLenum source,
657 GLenum type,
658 GLuint id,
659 GLenum severity,
660 GLsizei length,
661 const GLchar* message,
662 const GLvoid* userParam);
663 void DebugCallback(GLenum source,
664 GLenum type,
665 GLuint id,
666 GLenum severity,
667 GLsizei length,
668 const GLchar* message);
671 // -----------------------------------------------------------------------------
672 // MOZ_GL_DEBUG implementation
673 private:
675 #undef BEFORE_GL_CALL
676 #undef AFTER_GL_CALL
678 #ifdef DEBUG
680 #ifndef MOZ_FUNCTION_NAME
681 # ifdef __GNUC__
682 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
683 # elif defined(_MSC_VER)
684 # define MOZ_FUNCTION_NAME __FUNCTION__
685 # else
686 # define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
687 # endif
688 #endif
690 void BeforeGLCall(const char* glFunction) {
691 MOZ_ASSERT(IsCurrent());
692 if (DebugMode()) {
693 GLContext *currentGLContext = nullptr;
695 currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
697 if (DebugMode() & DebugTrace)
698 printf_stderr("[gl:%p] > %s\n", this, glFunction);
699 if (this != currentGLContext) {
700 printf_stderr("Fatal: %s called on non-current context %p. "
701 "The current context for this thread is %p.\n",
702 glFunction, this, currentGLContext);
703 NS_ABORT();
708 void AfterGLCall(const char* glFunction) {
709 if (DebugMode()) {
710 // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
711 // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
712 // tend to be meaningless
713 mSymbols.fFinish();
714 GLenum err = GetUnpushedError();
715 PushError(err);
717 if (DebugMode() & DebugTrace)
718 printf_stderr("[gl:%p] < %s [0x%04x]\n", this, glFunction, err);
720 if (err != LOCAL_GL_NO_ERROR) {
721 printf_stderr("GL ERROR: %s generated GL error %s(0x%04x)\n",
722 glFunction,
723 GLErrorToString(err),
724 err);
725 if (DebugMode() & DebugAbortOnError)
726 NS_ABORT();
731 GLContext *TrackingContext()
733 GLContext *tip = this;
734 while (tip->mSharedContext)
735 tip = tip->mSharedContext;
736 return tip;
739 static void AssertNotPassingStackBufferToTheGL(const void* ptr);
741 #define BEFORE_GL_CALL \
742 do { \
743 BeforeGLCall(MOZ_FUNCTION_NAME); \
744 } while (0)
746 #define AFTER_GL_CALL \
747 do { \
748 AfterGLCall(MOZ_FUNCTION_NAME); \
749 } while (0)
751 #define TRACKING_CONTEXT(a) \
752 do { \
753 TrackingContext()->a; \
754 } while (0)
756 #define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
758 #else // ifdef DEBUG
760 #define BEFORE_GL_CALL do { } while (0)
761 #define AFTER_GL_CALL do { } while (0)
762 #define TRACKING_CONTEXT(a) do {} while (0)
763 #define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
765 #endif // ifdef DEBUG
767 #define ASSERT_SYMBOL_PRESENT(func) \
768 do {\
769 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
770 if (MOZ_UNLIKELY(!mSymbols.func)) {\
771 printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
772 MOZ_CRASH();\
774 } while (0)
776 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
777 // bound.
778 void BeforeGLDrawCall() {
781 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
782 // if it's bound.
783 void AfterGLDrawCall()
785 if (mScreen)
786 mScreen->AfterDrawCall();
789 // Do whatever setup is necessary to read from our offscreen FBO, if it's
790 // bound.
791 void BeforeGLReadCall()
793 if (mScreen)
794 mScreen->BeforeReadCall();
797 // Do whatever tear-down is necessary after reading from our offscreen FBO,
798 // if it's bound.
799 void AfterGLReadCall() {
803 // -----------------------------------------------------------------------------
804 // GL official entry points
805 public:
807 void fActiveTexture(GLenum texture) {
808 BEFORE_GL_CALL;
809 mSymbols.fActiveTexture(texture);
810 AFTER_GL_CALL;
813 void fAttachShader(GLuint program, GLuint shader) {
814 BEFORE_GL_CALL;
815 mSymbols.fAttachShader(program, shader);
816 AFTER_GL_CALL;
819 void fBeginQuery(GLenum target, GLuint id) {
820 BEFORE_GL_CALL;
821 ASSERT_SYMBOL_PRESENT(fBeginQuery);
822 mSymbols.fBeginQuery(target, id);
823 AFTER_GL_CALL;
826 void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
827 BEFORE_GL_CALL;
828 mSymbols.fBindAttribLocation(program, index, name);
829 AFTER_GL_CALL;
832 void fBindBuffer(GLenum target, GLuint buffer) {
833 BEFORE_GL_CALL;
834 mSymbols.fBindBuffer(target, buffer);
835 AFTER_GL_CALL;
838 void fBindFramebuffer(GLenum target, GLuint framebuffer) {
839 if (!mScreen) {
840 raw_fBindFramebuffer(target, framebuffer);
841 return;
844 switch (target) {
845 case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
846 mScreen->BindDrawFB(framebuffer);
847 return;
849 case LOCAL_GL_READ_FRAMEBUFFER_EXT:
850 mScreen->BindReadFB(framebuffer);
851 return;
853 case LOCAL_GL_FRAMEBUFFER:
854 mScreen->BindFB(framebuffer);
855 return;
857 default:
858 // Nothing we care about, likely an error.
859 break;
862 raw_fBindFramebuffer(target, framebuffer);
865 void fBindTexture(GLenum target, GLuint texture) {
866 BEFORE_GL_CALL;
867 mSymbols.fBindTexture(target, texture);
868 AFTER_GL_CALL;
871 void fBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
872 BEFORE_GL_CALL;
873 mSymbols.fBlendColor(red, green, blue, alpha);
874 AFTER_GL_CALL;
877 void fBlendEquation(GLenum mode) {
878 BEFORE_GL_CALL;
879 mSymbols.fBlendEquation(mode);
880 AFTER_GL_CALL;
883 void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
884 BEFORE_GL_CALL;
885 mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
886 AFTER_GL_CALL;
889 void fBlendFunc(GLenum sfactor, GLenum dfactor) {
890 BEFORE_GL_CALL;
891 mSymbols.fBlendFunc(sfactor, dfactor);
892 AFTER_GL_CALL;
895 void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
896 BEFORE_GL_CALL;
897 mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
898 AFTER_GL_CALL;
901 private:
902 void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
903 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
904 BEFORE_GL_CALL;
905 mSymbols.fBufferData(target, size, data, usage);
906 AFTER_GL_CALL;
909 public:
910 void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
911 raw_fBufferData(target, size, data, usage);
913 // bug 744888
914 if (WorkAroundDriverBugs() &&
915 !data &&
916 Vendor() == GLVendor::NVIDIA)
918 UniquePtr<char[]> buf = MakeUnique<char[]>(1);
919 buf[0] = 0;
920 fBufferSubData(target, size-1, 1, buf.get());
924 void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
925 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
926 BEFORE_GL_CALL;
927 mSymbols.fBufferSubData(target, offset, size, data);
928 AFTER_GL_CALL;
931 private:
932 void raw_fClear(GLbitfield mask) {
933 BEFORE_GL_CALL;
934 mSymbols.fClear(mask);
935 AFTER_GL_CALL;
938 public:
939 void fClear(GLbitfield mask) {
940 BeforeGLDrawCall();
941 raw_fClear(mask);
942 AfterGLDrawCall();
945 void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
946 BEFORE_GL_CALL;
947 mSymbols.fClearColor(r, g, b, a);
948 AFTER_GL_CALL;
951 void fClearStencil(GLint s) {
952 BEFORE_GL_CALL;
953 mSymbols.fClearStencil(s);
954 AFTER_GL_CALL;
957 void fClientActiveTexture(GLenum texture) {
958 BEFORE_GL_CALL;
959 mSymbols.fClientActiveTexture(texture);
960 AFTER_GL_CALL;
963 void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
964 BEFORE_GL_CALL;
965 mSymbols.fColorMask(red, green, blue, alpha);
966 AFTER_GL_CALL;
969 void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *pixels) {
970 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
971 BEFORE_GL_CALL;
972 mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
973 AFTER_GL_CALL;
976 void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) {
977 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
978 BEFORE_GL_CALL;
979 mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
980 AFTER_GL_CALL;
983 void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
984 if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
985 // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
986 // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
987 level = -1;
988 width = -1;
989 height = -1;
990 border = -1;
993 BeforeGLReadCall();
994 raw_fCopyTexImage2D(target, level, internalformat,
995 x, y, width, height, border);
996 AfterGLReadCall();
999 void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
1000 BeforeGLReadCall();
1001 raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
1002 x, y, width, height);
1003 AfterGLReadCall();
1006 void fCullFace(GLenum mode) {
1007 BEFORE_GL_CALL;
1008 mSymbols.fCullFace(mode);
1009 AFTER_GL_CALL;
1012 void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
1013 BEFORE_GL_CALL;
1014 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
1015 mSymbols.fDebugMessageCallback(callback, userParam);
1016 AFTER_GL_CALL;
1019 void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) {
1020 BEFORE_GL_CALL;
1021 ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
1022 mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
1023 AFTER_GL_CALL;
1026 void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
1027 BEFORE_GL_CALL;
1028 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
1029 mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
1030 AFTER_GL_CALL;
1033 void fDetachShader(GLuint program, GLuint shader) {
1034 BEFORE_GL_CALL;
1035 mSymbols.fDetachShader(program, shader);
1036 AFTER_GL_CALL;
1039 void fDepthFunc(GLenum func) {
1040 BEFORE_GL_CALL;
1041 mSymbols.fDepthFunc(func);
1042 AFTER_GL_CALL;
1045 void fDepthMask(realGLboolean flag) {
1046 BEFORE_GL_CALL;
1047 mSymbols.fDepthMask(flag);
1048 AFTER_GL_CALL;
1051 void fDisable(GLenum capability) {
1052 BEFORE_GL_CALL;
1053 mSymbols.fDisable(capability);
1054 AFTER_GL_CALL;
1057 void fDisableClientState(GLenum capability) {
1058 BEFORE_GL_CALL;
1059 mSymbols.fDisableClientState(capability);
1060 AFTER_GL_CALL;
1063 void fDisableVertexAttribArray(GLuint index) {
1064 BEFORE_GL_CALL;
1065 mSymbols.fDisableVertexAttribArray(index);
1066 AFTER_GL_CALL;
1069 void fDrawBuffer(GLenum mode) {
1070 BEFORE_GL_CALL;
1071 mSymbols.fDrawBuffer(mode);
1072 AFTER_GL_CALL;
1075 private:
1076 void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1077 BEFORE_GL_CALL;
1078 mSymbols.fDrawArrays(mode, first, count);
1079 AFTER_GL_CALL;
1082 void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
1083 BEFORE_GL_CALL;
1084 mSymbols.fDrawElements(mode, count, type, indices);
1085 AFTER_GL_CALL;
1088 public:
1089 void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1090 BeforeGLDrawCall();
1091 raw_fDrawArrays(mode, first, count);
1092 AfterGLDrawCall();
1095 void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
1096 BeforeGLDrawCall();
1097 raw_fDrawElements(mode, count, type, indices);
1098 AfterGLDrawCall();
1101 void fEnable(GLenum capability) {
1102 BEFORE_GL_CALL;
1103 mSymbols.fEnable(capability);
1104 AFTER_GL_CALL;
1107 void fEnableClientState(GLenum capability) {
1108 BEFORE_GL_CALL;
1109 mSymbols.fEnableClientState(capability);
1110 AFTER_GL_CALL;
1113 void fEnableVertexAttribArray(GLuint index) {
1114 BEFORE_GL_CALL;
1115 mSymbols.fEnableVertexAttribArray(index);
1116 AFTER_GL_CALL;
1119 void fEndQuery(GLenum target) {
1120 BEFORE_GL_CALL;
1121 ASSERT_SYMBOL_PRESENT(fEndQuery);
1122 mSymbols.fEndQuery(target);
1123 AFTER_GL_CALL;
1126 void fFinish() {
1127 BEFORE_GL_CALL;
1128 mSymbols.fFinish();
1129 AFTER_GL_CALL;
1132 void fFlush() {
1133 BEFORE_GL_CALL;
1134 mSymbols.fFlush();
1135 AFTER_GL_CALL;
1138 void fFrontFace(GLenum face) {
1139 BEFORE_GL_CALL;
1140 mSymbols.fFrontFace(face);
1141 AFTER_GL_CALL;
1144 void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1145 BEFORE_GL_CALL;
1146 mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
1147 AFTER_GL_CALL;
1150 void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1151 BEFORE_GL_CALL;
1152 mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
1153 AFTER_GL_CALL;
1156 void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
1157 BEFORE_GL_CALL;
1158 mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
1159 AFTER_GL_CALL;
1162 GLint fGetAttribLocation(GLuint program, const GLchar* name) {
1163 BEFORE_GL_CALL;
1164 GLint retval = mSymbols.fGetAttribLocation(program, name);
1165 AFTER_GL_CALL;
1166 return retval;
1169 private:
1170 void raw_fGetIntegerv(GLenum pname, GLint *params) {
1171 BEFORE_GL_CALL;
1172 mSymbols.fGetIntegerv(pname, params);
1173 AFTER_GL_CALL;
1176 public:
1178 void fGetIntegerv(GLenum pname, GLint *params) {
1179 switch (pname)
1181 // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
1182 // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
1183 // so we don't need two cases.
1184 case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
1185 if (mScreen) {
1186 *params = mScreen->GetDrawFB();
1187 } else {
1188 raw_fGetIntegerv(pname, params);
1190 break;
1192 case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
1193 if (mScreen) {
1194 *params = mScreen->GetReadFB();
1195 } else {
1196 raw_fGetIntegerv(pname, params);
1198 break;
1200 case LOCAL_GL_MAX_TEXTURE_SIZE:
1201 MOZ_ASSERT(mMaxTextureSize>0);
1202 *params = mMaxTextureSize;
1203 break;
1205 case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1206 MOZ_ASSERT(mMaxCubeMapTextureSize>0);
1207 *params = mMaxCubeMapTextureSize;
1208 break;
1210 case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
1211 MOZ_ASSERT(mMaxRenderbufferSize>0);
1212 *params = mMaxRenderbufferSize;
1213 break;
1215 case LOCAL_GL_VIEWPORT:
1216 for (size_t i = 0; i < 4; i++) {
1217 params[i] = mViewportRect[i];
1219 break;
1221 case LOCAL_GL_SCISSOR_BOX:
1222 for (size_t i = 0; i < 4; i++) {
1223 params[i] = mScissorRect[i];
1225 break;
1227 default:
1228 raw_fGetIntegerv(pname, params);
1229 break;
1233 void GetUIntegerv(GLenum pname, GLuint *params) {
1234 fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
1237 void fGetFloatv(GLenum pname, GLfloat *params) {
1238 BEFORE_GL_CALL;
1239 mSymbols.fGetFloatv(pname, params);
1240 AFTER_GL_CALL;
1243 void fGetBooleanv(GLenum pname, realGLboolean *params) {
1244 BEFORE_GL_CALL;
1245 mSymbols.fGetBooleanv(pname, params);
1246 AFTER_GL_CALL;
1249 void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
1250 BEFORE_GL_CALL;
1251 mSymbols.fGetBufferParameteriv(target, pname, params);
1252 AFTER_GL_CALL;
1255 GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
1256 BEFORE_GL_CALL;
1257 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
1258 GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
1259 AFTER_GL_CALL;
1260 return ret;
1263 void fGetPointerv(GLenum pname, GLvoid** params) {
1264 BEFORE_GL_CALL;
1265 ASSERT_SYMBOL_PRESENT(fGetPointerv);
1266 mSymbols.fGetPointerv(pname, params);
1267 AFTER_GL_CALL;
1270 void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
1271 BEFORE_GL_CALL;
1272 ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
1273 mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
1274 AFTER_GL_CALL;
1277 void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
1278 BEFORE_GL_CALL;
1279 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
1280 mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
1281 AFTER_GL_CALL;
1284 void fGenerateMipmap(GLenum target) {
1285 BEFORE_GL_CALL;
1286 mSymbols.fGenerateMipmap(target);
1287 AFTER_GL_CALL;
1290 void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
1291 BEFORE_GL_CALL;
1292 mSymbols.fGetProgramiv(program, pname, param);
1293 AFTER_GL_CALL;
1296 void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1297 BEFORE_GL_CALL;
1298 mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
1299 AFTER_GL_CALL;
1302 void fTexParameteri(GLenum target, GLenum pname, GLint param) {
1303 BEFORE_GL_CALL;
1304 mSymbols.fTexParameteri(target, pname, param);
1305 AFTER_GL_CALL;
1308 void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
1309 BEFORE_GL_CALL;
1310 mSymbols.fTexParameteriv(target, pname, params);
1311 AFTER_GL_CALL;
1314 void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
1315 BEFORE_GL_CALL;
1316 mSymbols.fTexParameterf(target, pname, param);
1317 AFTER_GL_CALL;
1320 const GLubyte* fGetString(GLenum name) {
1321 BEFORE_GL_CALL;
1322 const GLubyte *result = mSymbols.fGetString(name);
1323 AFTER_GL_CALL;
1324 return result;
1327 void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) {
1328 BEFORE_GL_CALL;
1329 ASSERT_SYMBOL_PRESENT(fGetTexImage);
1330 mSymbols.fGetTexImage(target, level, format, type, img);
1331 AFTER_GL_CALL;
1334 void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
1336 BEFORE_GL_CALL;
1337 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
1338 mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
1339 AFTER_GL_CALL;
1342 void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
1343 BEFORE_GL_CALL;
1344 mSymbols.fGetTexParameterfv(target, pname, params);
1345 AFTER_GL_CALL;
1348 void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
1349 BEFORE_GL_CALL;
1350 mSymbols.fGetTexParameteriv(target, pname, params);
1351 AFTER_GL_CALL;
1354 void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
1355 BEFORE_GL_CALL;
1356 mSymbols.fGetUniformfv(program, location, params);
1357 AFTER_GL_CALL;
1360 void fGetUniformiv(GLuint program, GLint location, GLint* params) {
1361 BEFORE_GL_CALL;
1362 mSymbols.fGetUniformiv(program, location, params);
1363 AFTER_GL_CALL;
1366 GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
1367 BEFORE_GL_CALL;
1368 GLint retval = mSymbols.fGetUniformLocation(programObj, name);
1369 AFTER_GL_CALL;
1370 return retval;
1373 void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
1374 BEFORE_GL_CALL;
1375 mSymbols.fGetVertexAttribfv(index, pname, retval);
1376 AFTER_GL_CALL;
1379 void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
1380 BEFORE_GL_CALL;
1381 mSymbols.fGetVertexAttribiv(index, pname, retval);
1382 AFTER_GL_CALL;
1385 void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
1386 BEFORE_GL_CALL;
1387 mSymbols.fGetVertexAttribPointerv(index, pname, retval);
1388 AFTER_GL_CALL;
1391 void fHint(GLenum target, GLenum mode) {
1392 BEFORE_GL_CALL;
1393 mSymbols.fHint(target, mode);
1394 AFTER_GL_CALL;
1397 realGLboolean fIsBuffer(GLuint buffer) {
1398 BEFORE_GL_CALL;
1399 realGLboolean retval = mSymbols.fIsBuffer(buffer);
1400 AFTER_GL_CALL;
1401 return retval;
1404 realGLboolean fIsEnabled(GLenum capability) {
1405 BEFORE_GL_CALL;
1406 realGLboolean retval = mSymbols.fIsEnabled(capability);
1407 AFTER_GL_CALL;
1408 return retval;
1411 realGLboolean fIsProgram(GLuint program) {
1412 BEFORE_GL_CALL;
1413 realGLboolean retval = mSymbols.fIsProgram(program);
1414 AFTER_GL_CALL;
1415 return retval;
1418 realGLboolean fIsShader(GLuint shader) {
1419 BEFORE_GL_CALL;
1420 realGLboolean retval = mSymbols.fIsShader(shader);
1421 AFTER_GL_CALL;
1422 return retval;
1425 realGLboolean fIsTexture(GLuint texture) {
1426 BEFORE_GL_CALL;
1427 realGLboolean retval = mSymbols.fIsTexture(texture);
1428 AFTER_GL_CALL;
1429 return retval;
1432 void fLineWidth(GLfloat width) {
1433 BEFORE_GL_CALL;
1434 mSymbols.fLineWidth(width);
1435 AFTER_GL_CALL;
1438 void fLinkProgram(GLuint program) {
1439 BEFORE_GL_CALL;
1440 mSymbols.fLinkProgram(program);
1441 AFTER_GL_CALL;
1444 void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) {
1445 BEFORE_GL_CALL;
1446 ASSERT_SYMBOL_PRESENT(fObjectLabel);
1447 mSymbols.fObjectLabel(identifier, name, length, label);
1448 AFTER_GL_CALL;
1451 void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
1452 BEFORE_GL_CALL;
1453 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
1454 mSymbols.fObjectPtrLabel(ptr, length, label);
1455 AFTER_GL_CALL;
1458 void fLoadIdentity() {
1459 BEFORE_GL_CALL;
1460 mSymbols.fLoadIdentity();
1461 AFTER_GL_CALL;
1464 void fLoadMatrixf(const GLfloat *matrix) {
1465 BEFORE_GL_CALL;
1466 mSymbols.fLoadMatrixf(matrix);
1467 AFTER_GL_CALL;
1470 void fMatrixMode(GLenum mode) {
1471 BEFORE_GL_CALL;
1472 mSymbols.fMatrixMode(mode);
1473 AFTER_GL_CALL;
1476 void fPixelStorei(GLenum pname, GLint param) {
1477 BEFORE_GL_CALL;
1478 mSymbols.fPixelStorei(pname, param);
1479 AFTER_GL_CALL;
1482 void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid *pointer) {
1483 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer);
1484 BEFORE_GL_CALL;
1485 mSymbols.fTextureRangeAPPLE(target, length, pointer);
1486 AFTER_GL_CALL;
1489 void fPointParameterf(GLenum pname, GLfloat param) {
1490 BEFORE_GL_CALL;
1491 mSymbols.fPointParameterf(pname, param);
1492 AFTER_GL_CALL;
1495 void fPolygonOffset(GLfloat factor, GLfloat bias) {
1496 BEFORE_GL_CALL;
1497 mSymbols.fPolygonOffset(factor, bias);
1498 AFTER_GL_CALL;
1501 void fPopDebugGroup() {
1502 BEFORE_GL_CALL;
1503 ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
1504 mSymbols.fPopDebugGroup();
1505 AFTER_GL_CALL;
1508 void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
1509 BEFORE_GL_CALL;
1510 ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
1511 mSymbols.fPushDebugGroup(source, id, length, message);
1512 AFTER_GL_CALL;
1515 void fReadBuffer(GLenum mode) {
1516 BEFORE_GL_CALL;
1517 mSymbols.fReadBuffer(mode);
1518 AFTER_GL_CALL;
1521 private:
1522 void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
1523 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1524 BEFORE_GL_CALL;
1525 mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
1526 AFTER_GL_CALL;
1529 public:
1530 void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
1531 BeforeGLReadCall();
1533 bool didReadPixels = false;
1534 if (mScreen) {
1535 didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels);
1538 if (!didReadPixels) {
1539 raw_fReadPixels(x, y, width, height, format, type, pixels);
1542 AfterGLReadCall();
1545 public:
1546 void fSampleCoverage(GLclampf value, realGLboolean invert) {
1547 BEFORE_GL_CALL;
1548 mSymbols.fSampleCoverage(value, invert);
1549 AFTER_GL_CALL;
1552 void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1553 if (mScissorRect[0] == x &&
1554 mScissorRect[1] == y &&
1555 mScissorRect[2] == width &&
1556 mScissorRect[3] == height)
1558 return;
1560 mScissorRect[0] = x;
1561 mScissorRect[1] = y;
1562 mScissorRect[2] = width;
1563 mScissorRect[3] = height;
1564 BEFORE_GL_CALL;
1565 mSymbols.fScissor(x, y, width, height);
1566 AFTER_GL_CALL;
1569 void fStencilFunc(GLenum func, GLint ref, GLuint mask) {
1570 BEFORE_GL_CALL;
1571 mSymbols.fStencilFunc(func, ref, mask);
1572 AFTER_GL_CALL;
1575 void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {
1576 BEFORE_GL_CALL;
1577 mSymbols.fStencilFuncSeparate(frontfunc, backfunc, ref, mask);
1578 AFTER_GL_CALL;
1581 void fStencilMask(GLuint mask) {
1582 BEFORE_GL_CALL;
1583 mSymbols.fStencilMask(mask);
1584 AFTER_GL_CALL;
1587 void fStencilMaskSeparate(GLenum face, GLuint mask) {
1588 BEFORE_GL_CALL;
1589 mSymbols.fStencilMaskSeparate(face, mask);
1590 AFTER_GL_CALL;
1593 void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
1594 BEFORE_GL_CALL;
1595 mSymbols.fStencilOp(fail, zfail, zpass);
1596 AFTER_GL_CALL;
1599 void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
1600 BEFORE_GL_CALL;
1601 mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
1602 AFTER_GL_CALL;
1605 void fTexGeni(GLenum coord, GLenum pname, GLint param) {
1606 BEFORE_GL_CALL;
1607 mSymbols.fTexGeni(coord, pname, param);
1608 AFTER_GL_CALL;
1611 void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
1612 BEFORE_GL_CALL;
1613 mSymbols.fTexGenf(coord, pname, param);
1614 AFTER_GL_CALL;
1617 void fTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) {
1618 BEFORE_GL_CALL;
1619 mSymbols.fTexGenfv(coord, pname, params);
1620 AFTER_GL_CALL;
1623 private:
1624 void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
1625 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1626 BEFORE_GL_CALL;
1627 mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1628 AFTER_GL_CALL;
1631 public:
1632 void fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
1633 if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
1634 // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
1635 // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
1636 level = -1;
1637 width = -1;
1638 height = -1;
1639 border = -1;
1641 raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1644 void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
1645 ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1646 BEFORE_GL_CALL;
1647 mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
1648 AFTER_GL_CALL;
1651 void fUniform1f(GLint location, GLfloat v0) {
1652 BEFORE_GL_CALL;
1653 mSymbols.fUniform1f(location, v0);
1654 AFTER_GL_CALL;
1657 void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
1658 BEFORE_GL_CALL;
1659 mSymbols.fUniform1fv(location, count, value);
1660 AFTER_GL_CALL;
1663 void fUniform1i(GLint location, GLint v0) {
1664 BEFORE_GL_CALL;
1665 mSymbols.fUniform1i(location, v0);
1666 AFTER_GL_CALL;
1669 void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
1670 BEFORE_GL_CALL;
1671 mSymbols.fUniform1iv(location, count, value);
1672 AFTER_GL_CALL;
1675 void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
1676 BEFORE_GL_CALL;
1677 mSymbols.fUniform2f(location, v0, v1);
1678 AFTER_GL_CALL;
1681 void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
1682 BEFORE_GL_CALL;
1683 mSymbols.fUniform2fv(location, count, value);
1684 AFTER_GL_CALL;
1687 void fUniform2i(GLint location, GLint v0, GLint v1) {
1688 BEFORE_GL_CALL;
1689 mSymbols.fUniform2i(location, v0, v1);
1690 AFTER_GL_CALL;
1693 void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
1694 BEFORE_GL_CALL;
1695 mSymbols.fUniform2iv(location, count, value);
1696 AFTER_GL_CALL;
1699 void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
1700 BEFORE_GL_CALL;
1701 mSymbols.fUniform3f(location, v0, v1, v2);
1702 AFTER_GL_CALL;
1705 void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
1706 BEFORE_GL_CALL;
1707 mSymbols.fUniform3fv(location, count, value);
1708 AFTER_GL_CALL;
1711 void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
1712 BEFORE_GL_CALL;
1713 mSymbols.fUniform3i(location, v0, v1, v2);
1714 AFTER_GL_CALL;
1717 void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
1718 BEFORE_GL_CALL;
1719 mSymbols.fUniform3iv(location, count, value);
1720 AFTER_GL_CALL;
1723 void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
1724 BEFORE_GL_CALL;
1725 mSymbols.fUniform4f(location, v0, v1, v2, v3);
1726 AFTER_GL_CALL;
1729 void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
1730 BEFORE_GL_CALL;
1731 mSymbols.fUniform4fv(location, count, value);
1732 AFTER_GL_CALL;
1735 void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
1736 BEFORE_GL_CALL;
1737 mSymbols.fUniform4i(location, v0, v1, v2, v3);
1738 AFTER_GL_CALL;
1741 void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
1742 BEFORE_GL_CALL;
1743 mSymbols.fUniform4iv(location, count, value);
1744 AFTER_GL_CALL;
1747 void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1748 BEFORE_GL_CALL;
1749 mSymbols.fUniformMatrix2fv(location, count, transpose, value);
1750 AFTER_GL_CALL;
1753 void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1754 BEFORE_GL_CALL;
1755 mSymbols.fUniformMatrix3fv(location, count, transpose, value);
1756 AFTER_GL_CALL;
1759 void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1760 BEFORE_GL_CALL;
1761 mSymbols.fUniformMatrix4fv(location, count, transpose, value);
1762 AFTER_GL_CALL;
1765 void fUseProgram(GLuint program) {
1766 BEFORE_GL_CALL;
1767 mSymbols.fUseProgram(program);
1768 AFTER_GL_CALL;
1771 void fValidateProgram(GLuint program) {
1772 BEFORE_GL_CALL;
1773 mSymbols.fValidateProgram(program);
1774 AFTER_GL_CALL;
1777 void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
1778 BEFORE_GL_CALL;
1779 mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
1780 AFTER_GL_CALL;
1783 void fVertexAttrib1f(GLuint index, GLfloat x) {
1784 BEFORE_GL_CALL;
1785 mSymbols.fVertexAttrib1f(index, x);
1786 AFTER_GL_CALL;
1789 void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1790 BEFORE_GL_CALL;
1791 mSymbols.fVertexAttrib2f(index, x, y);
1792 AFTER_GL_CALL;
1795 void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1796 BEFORE_GL_CALL;
1797 mSymbols.fVertexAttrib3f(index, x, y, z);
1798 AFTER_GL_CALL;
1801 void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
1802 BEFORE_GL_CALL;
1803 mSymbols.fVertexAttrib4f(index, x, y, z, w);
1804 AFTER_GL_CALL;
1807 void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
1808 BEFORE_GL_CALL;
1809 mSymbols.fVertexAttrib1fv(index, v);
1810 AFTER_GL_CALL;
1813 void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
1814 BEFORE_GL_CALL;
1815 mSymbols.fVertexAttrib2fv(index, v);
1816 AFTER_GL_CALL;
1819 void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
1820 BEFORE_GL_CALL;
1821 mSymbols.fVertexAttrib3fv(index, v);
1822 AFTER_GL_CALL;
1825 void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
1826 BEFORE_GL_CALL;
1827 mSymbols.fVertexAttrib4fv(index, v);
1828 AFTER_GL_CALL;
1831 void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
1832 BEFORE_GL_CALL;
1833 mSymbols.fVertexPointer(size, type, stride, pointer);
1834 AFTER_GL_CALL;
1837 void fCompileShader(GLuint shader) {
1838 BEFORE_GL_CALL;
1839 mSymbols.fCompileShader(shader);
1840 AFTER_GL_CALL;
1843 private:
1844 void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
1845 BEFORE_GL_CALL;
1846 mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
1847 AFTER_GL_CALL;
1850 void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
1851 BEFORE_GL_CALL;
1852 mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
1853 AFTER_GL_CALL;
1856 public:
1857 void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
1858 BEFORE_GL_CALL;
1859 mSymbols.fGetShaderiv(shader, pname, param);
1860 AFTER_GL_CALL;
1863 void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1864 BEFORE_GL_CALL;
1865 mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
1866 AFTER_GL_CALL;
1869 private:
1870 void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1871 MOZ_ASSERT(IsGLES());
1873 BEFORE_GL_CALL;
1874 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
1875 mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1876 AFTER_GL_CALL;
1879 public:
1880 void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1881 if (IsGLES()) {
1882 raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1883 } else {
1884 // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
1885 GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
1889 void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
1890 BEFORE_GL_CALL;
1891 mSymbols.fGetShaderSource(obj, maxLength, length, source);
1892 AFTER_GL_CALL;
1895 void fShaderSource(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) {
1896 BEFORE_GL_CALL;
1897 mSymbols.fShaderSource(shader, count, strings, lengths);
1898 AFTER_GL_CALL;
1901 private:
1902 void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
1903 BEFORE_GL_CALL;
1904 mSymbols.fBindFramebuffer(target, framebuffer);
1905 AFTER_GL_CALL;
1908 public:
1909 void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
1910 BEFORE_GL_CALL;
1911 mSymbols.fBindRenderbuffer(target, renderbuffer);
1912 AFTER_GL_CALL;
1915 GLenum fCheckFramebufferStatus(GLenum target) {
1916 BEFORE_GL_CALL;
1917 GLenum retval = mSymbols.fCheckFramebufferStatus(target);
1918 AFTER_GL_CALL;
1919 return retval;
1922 void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
1923 BEFORE_GL_CALL;
1924 mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
1925 AFTER_GL_CALL;
1928 void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
1929 BEFORE_GL_CALL;
1930 mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
1931 AFTER_GL_CALL;
1934 void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
1935 BEFORE_GL_CALL;
1936 mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
1937 AFTER_GL_CALL;
1940 void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
1941 BEFORE_GL_CALL;
1942 mSymbols.fGetRenderbufferParameteriv(target, pname, value);
1943 AFTER_GL_CALL;
1946 realGLboolean fIsFramebuffer (GLuint framebuffer) {
1947 BEFORE_GL_CALL;
1948 realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
1949 AFTER_GL_CALL;
1950 return retval;
1953 public:
1954 realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
1955 BEFORE_GL_CALL;
1956 realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
1957 AFTER_GL_CALL;
1958 return retval;
1961 void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
1962 BEFORE_GL_CALL;
1963 mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
1964 AFTER_GL_CALL;
1967 private:
1968 void raw_fDepthRange(GLclampf a, GLclampf b) {
1969 MOZ_ASSERT(!IsGLES());
1971 BEFORE_GL_CALL;
1972 ASSERT_SYMBOL_PRESENT(fDepthRange);
1973 mSymbols.fDepthRange(a, b);
1974 AFTER_GL_CALL;
1977 void raw_fDepthRangef(GLclampf a, GLclampf b) {
1978 MOZ_ASSERT(IsGLES());
1980 BEFORE_GL_CALL;
1981 ASSERT_SYMBOL_PRESENT(fDepthRangef);
1982 mSymbols.fDepthRangef(a, b);
1983 AFTER_GL_CALL;
1986 void raw_fClearDepth(GLclampf v) {
1987 MOZ_ASSERT(!IsGLES());
1989 BEFORE_GL_CALL;
1990 ASSERT_SYMBOL_PRESENT(fClearDepth);
1991 mSymbols.fClearDepth(v);
1992 AFTER_GL_CALL;
1995 void raw_fClearDepthf(GLclampf v) {
1996 MOZ_ASSERT(IsGLES());
1998 BEFORE_GL_CALL;
1999 ASSERT_SYMBOL_PRESENT(fClearDepthf);
2000 mSymbols.fClearDepthf(v);
2001 AFTER_GL_CALL;
2004 public:
2005 void fDepthRange(GLclampf a, GLclampf b) {
2006 if (IsGLES()) {
2007 raw_fDepthRangef(a, b);
2008 } else {
2009 raw_fDepthRange(a, b);
2013 void fClearDepth(GLclampf v) {
2014 if (IsGLES()) {
2015 raw_fClearDepthf(v);
2016 } else {
2017 raw_fClearDepth(v);
2021 void* fMapBuffer(GLenum target, GLenum access) {
2022 BEFORE_GL_CALL;
2023 ASSERT_SYMBOL_PRESENT(fMapBuffer);
2024 void *ret = mSymbols.fMapBuffer(target, access);
2025 AFTER_GL_CALL;
2026 return ret;
2029 realGLboolean fUnmapBuffer(GLenum target) {
2030 BEFORE_GL_CALL;
2031 ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
2032 realGLboolean ret = mSymbols.fUnmapBuffer(target);
2033 AFTER_GL_CALL;
2034 return ret;
2038 private:
2039 GLuint raw_fCreateProgram() {
2040 BEFORE_GL_CALL;
2041 GLuint ret = mSymbols.fCreateProgram();
2042 AFTER_GL_CALL;
2043 return ret;
2046 GLuint raw_fCreateShader(GLenum t) {
2047 BEFORE_GL_CALL;
2048 GLuint ret = mSymbols.fCreateShader(t);
2049 AFTER_GL_CALL;
2050 return ret;
2053 void raw_fGenBuffers(GLsizei n, GLuint* names) {
2054 BEFORE_GL_CALL;
2055 mSymbols.fGenBuffers(n, names);
2056 AFTER_GL_CALL;
2059 void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
2060 BEFORE_GL_CALL;
2061 mSymbols.fGenFramebuffers(n, names);
2062 AFTER_GL_CALL;
2065 void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
2066 BEFORE_GL_CALL;
2067 mSymbols.fGenRenderbuffers(n, names);
2068 AFTER_GL_CALL;
2071 void raw_fGenTextures(GLsizei n, GLuint* names) {
2072 BEFORE_GL_CALL;
2073 mSymbols.fGenTextures(n, names);
2074 AFTER_GL_CALL;
2077 public:
2078 GLuint fCreateProgram() {
2079 GLuint ret = raw_fCreateProgram();
2080 TRACKING_CONTEXT(CreatedProgram(this, ret));
2081 return ret;
2084 GLuint fCreateShader(GLenum t) {
2085 GLuint ret = raw_fCreateShader(t);
2086 TRACKING_CONTEXT(CreatedShader(this, ret));
2087 return ret;
2090 void fGenBuffers(GLsizei n, GLuint* names) {
2091 raw_fGenBuffers(n, names);
2092 TRACKING_CONTEXT(CreatedBuffers(this, n, names));
2095 void fGenFramebuffers(GLsizei n, GLuint* names) {
2096 raw_fGenFramebuffers(n, names);
2097 TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
2100 void fGenRenderbuffers(GLsizei n, GLuint* names) {
2101 raw_fGenRenderbuffers(n, names);
2102 TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
2105 void fGenTextures(GLsizei n, GLuint* names) {
2106 raw_fGenTextures(n, names);
2107 TRACKING_CONTEXT(CreatedTextures(this, n, names));
2110 private:
2111 void raw_fDeleteProgram(GLuint program) {
2112 BEFORE_GL_CALL;
2113 mSymbols.fDeleteProgram(program);
2114 AFTER_GL_CALL;
2117 void raw_fDeleteShader(GLuint shader) {
2118 BEFORE_GL_CALL;
2119 mSymbols.fDeleteShader(shader);
2120 AFTER_GL_CALL;
2123 void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
2124 BEFORE_GL_CALL;
2125 mSymbols.fDeleteBuffers(n, names);
2126 AFTER_GL_CALL;
2129 void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2130 BEFORE_GL_CALL;
2131 mSymbols.fDeleteFramebuffers(n, names);
2132 AFTER_GL_CALL;
2135 void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2136 BEFORE_GL_CALL;
2137 mSymbols.fDeleteRenderbuffers(n, names);
2138 AFTER_GL_CALL;
2141 void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
2142 BEFORE_GL_CALL;
2143 mSymbols.fDeleteTextures(n, names);
2144 AFTER_GL_CALL;
2147 public:
2149 void fDeleteProgram(GLuint program) {
2150 raw_fDeleteProgram(program);
2151 TRACKING_CONTEXT(DeletedProgram(this, program));
2154 void fDeleteShader(GLuint shader) {
2155 raw_fDeleteShader(shader);
2156 TRACKING_CONTEXT(DeletedShader(this, shader));
2159 void fDeleteBuffers(GLsizei n, const GLuint* names) {
2160 raw_fDeleteBuffers(n, names);
2161 TRACKING_CONTEXT(DeletedBuffers(this, n, names));
2164 void fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2165 if (mScreen) {
2166 // Notify mScreen which framebuffers we're deleting.
2167 // Otherwise, we will get framebuffer binding mispredictions.
2168 for (int i = 0; i < n; i++) {
2169 mScreen->DeletingFB(names[i]);
2173 if (n == 1 && *names == 0) {
2174 // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
2175 } else {
2176 raw_fDeleteFramebuffers(n, names);
2178 TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
2181 void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2182 raw_fDeleteRenderbuffers(n, names);
2183 TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
2186 void fDeleteTextures(GLsizei n, const GLuint* names) {
2187 raw_fDeleteTextures(n, names);
2188 TRACKING_CONTEXT(DeletedTextures(this, n, names));
2191 GLenum fGetGraphicsResetStatus() {
2192 MOZ_ASSERT(mHasRobustness);
2194 BEFORE_GL_CALL;
2195 ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
2196 GLenum ret = mSymbols.fGetGraphicsResetStatus();
2197 AFTER_GL_CALL;
2198 return ret;
2202 // -----------------------------------------------------------------------------
2203 // Extension ARB_sync (GL)
2204 public:
2205 GLsync fFenceSync(GLenum condition, GLbitfield flags) {
2206 BEFORE_GL_CALL;
2207 ASSERT_SYMBOL_PRESENT(fFenceSync);
2208 GLsync ret = mSymbols.fFenceSync(condition, flags);
2209 AFTER_GL_CALL;
2210 return ret;
2213 realGLboolean fIsSync(GLsync sync) {
2214 BEFORE_GL_CALL;
2215 ASSERT_SYMBOL_PRESENT(fIsSync);
2216 realGLboolean ret = mSymbols.fIsSync(sync);
2217 AFTER_GL_CALL;
2218 return ret;
2221 void fDeleteSync(GLsync sync) {
2222 BEFORE_GL_CALL;
2223 ASSERT_SYMBOL_PRESENT(fDeleteSync);
2224 mSymbols.fDeleteSync(sync);
2225 AFTER_GL_CALL;
2228 GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2229 BEFORE_GL_CALL;
2230 ASSERT_SYMBOL_PRESENT(fClientWaitSync);
2231 GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
2232 AFTER_GL_CALL;
2233 return ret;
2236 void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2237 BEFORE_GL_CALL;
2238 ASSERT_SYMBOL_PRESENT(fWaitSync);
2239 mSymbols.fWaitSync(sync, flags, timeout);
2240 AFTER_GL_CALL;
2243 void fGetInteger64v(GLenum pname, GLint64 *params) {
2244 BEFORE_GL_CALL;
2245 ASSERT_SYMBOL_PRESENT(fGetInteger64v);
2246 mSymbols.fGetInteger64v(pname, params);
2247 AFTER_GL_CALL;
2250 void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
2251 BEFORE_GL_CALL;
2252 ASSERT_SYMBOL_PRESENT(fGetSynciv);
2253 mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
2254 AFTER_GL_CALL;
2258 // -----------------------------------------------------------------------------
2259 // Extension OES_EGL_image (GLES)
2260 public:
2261 void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
2262 BEFORE_GL_CALL;
2263 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
2264 mSymbols.fEGLImageTargetTexture2D(target, image);
2265 AFTER_GL_CALL;
2268 void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
2270 BEFORE_GL_CALL;
2271 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
2272 mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
2273 AFTER_GL_CALL;
2277 // -----------------------------------------------------------------------------
2278 // Package XXX_bind_buffer_offset
2279 public:
2280 void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
2282 BEFORE_GL_CALL;
2283 ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
2284 mSymbols.fBindBufferOffset(target, index, buffer, offset);
2285 AFTER_GL_CALL;
2289 // -----------------------------------------------------------------------------
2290 // Package XXX_draw_buffers
2291 public:
2292 void fDrawBuffers(GLsizei n, const GLenum* bufs) {
2293 BEFORE_GL_CALL;
2294 mSymbols.fDrawBuffers(n, bufs);
2295 AFTER_GL_CALL;
2299 // -----------------------------------------------------------------------------
2300 // Package XXX_draw_instanced
2301 public:
2302 void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2304 BeforeGLDrawCall();
2305 raw_fDrawArraysInstanced(mode, first, count, primcount);
2306 AfterGLDrawCall();
2309 void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2311 BeforeGLDrawCall();
2312 raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
2313 AfterGLDrawCall();
2316 private:
2317 void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2319 BEFORE_GL_CALL;
2320 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
2321 mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
2322 AFTER_GL_CALL;
2325 void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2327 BEFORE_GL_CALL;
2328 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
2329 mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
2330 AFTER_GL_CALL;
2333 // -----------------------------------------------------------------------------
2334 // Feature draw_range_elements
2335 public:
2336 void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2337 GLsizei count, GLenum type, const GLvoid* indices)
2339 BeforeGLDrawCall();
2340 raw_fDrawRangeElements(mode, start, end, count, type, indices);
2341 AfterGLDrawCall();
2344 private:
2345 void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2346 GLsizei count, GLenum type, const GLvoid* indices)
2348 BEFORE_GL_CALL;
2349 ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
2350 mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
2351 AFTER_GL_CALL;
2354 // -----------------------------------------------------------------------------
2355 // Package XXX_framebuffer_blit
2356 public:
2357 // Draw/Read
2358 void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2359 BeforeGLDrawCall();
2360 BeforeGLReadCall();
2361 raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2362 AfterGLReadCall();
2363 AfterGLDrawCall();
2367 private:
2368 void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2369 BEFORE_GL_CALL;
2370 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
2371 mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2372 AFTER_GL_CALL;
2376 // -----------------------------------------------------------------------------
2377 // Package XXX_framebuffer_multisample
2378 public:
2379 void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
2380 BEFORE_GL_CALL;
2381 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
2382 mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
2383 AFTER_GL_CALL;
2387 // -----------------------------------------------------------------------------
2388 // Package XXX_instanced_arrays
2389 public:
2390 void fVertexAttribDivisor(GLuint index, GLuint divisor)
2392 BEFORE_GL_CALL;
2393 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
2394 mSymbols.fVertexAttribDivisor(index, divisor);
2395 AFTER_GL_CALL;
2399 // -----------------------------------------------------------------------------
2400 // Package XXX_query_objects
2402 * XXX_query_objects:
2403 * - provide all followed entry points
2405 * XXX_occlusion_query2:
2406 * - depends on XXX_query_objects
2407 * - provide ANY_SAMPLES_PASSED
2409 * XXX_occlusion_query_boolean:
2410 * - depends on XXX_occlusion_query2
2411 * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2413 public:
2414 void fDeleteQueries(GLsizei n, const GLuint* names) {
2415 BEFORE_GL_CALL;
2416 ASSERT_SYMBOL_PRESENT(fDeleteQueries);
2417 mSymbols.fDeleteQueries(n, names);
2418 AFTER_GL_CALL;
2419 TRACKING_CONTEXT(DeletedQueries(this, n, names));
2422 void fGenQueries(GLsizei n, GLuint* names) {
2423 BEFORE_GL_CALL;
2424 ASSERT_SYMBOL_PRESENT(fGenQueries);
2425 mSymbols.fGenQueries(n, names);
2426 AFTER_GL_CALL;
2427 TRACKING_CONTEXT(CreatedQueries(this, n, names));
2430 void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
2431 BEFORE_GL_CALL;
2432 ASSERT_SYMBOL_PRESENT(fGetQueryiv);
2433 mSymbols.fGetQueryiv(target, pname, params);
2434 AFTER_GL_CALL;
2437 void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
2438 BEFORE_GL_CALL;
2439 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
2440 mSymbols.fGetQueryObjectuiv(id, pname, params);
2441 AFTER_GL_CALL;
2444 realGLboolean fIsQuery(GLuint query) {
2445 BEFORE_GL_CALL;
2446 ASSERT_SYMBOL_PRESENT(fIsQuery);
2447 realGLboolean retval = mSymbols.fIsQuery(query);
2448 AFTER_GL_CALL;
2449 return retval;
2453 // -----------------------------------------------------------------------------
2454 // Package XXX_get_query_object_iv
2456 * XXX_get_query_object_iv:
2457 * - depends on XXX_query_objects
2458 * - provide the followed entry point
2460 * XXX_occlusion_query:
2461 * - depends on XXX_get_query_object_iv
2462 * - provide LOCAL_GL_SAMPLES_PASSED
2464 public:
2465 void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
2466 BEFORE_GL_CALL;
2467 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
2468 mSymbols.fGetQueryObjectiv(id, pname, params);
2469 AFTER_GL_CALL;
2473 // -----------------------------------------------------------------------------
2474 // Package XXX_transform_feedback
2475 public:
2476 void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
2478 BEFORE_GL_CALL;
2479 ASSERT_SYMBOL_PRESENT(fBindBufferBase);
2480 mSymbols.fBindBufferBase(target, index, buffer);
2481 AFTER_GL_CALL;
2484 void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
2486 BEFORE_GL_CALL;
2487 ASSERT_SYMBOL_PRESENT(fBindBufferRange);
2488 mSymbols.fBindBufferRange(target, index, buffer, offset, size);
2489 AFTER_GL_CALL;
2492 void fBeginTransformFeedback(GLenum primitiveMode)
2494 BEFORE_GL_CALL;
2495 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
2496 mSymbols.fBeginTransformFeedback(primitiveMode);
2497 AFTER_GL_CALL;
2500 void fEndTransformFeedback()
2502 BEFORE_GL_CALL;
2503 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
2504 mSymbols.fEndTransformFeedback();
2505 AFTER_GL_CALL;
2508 void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
2510 BEFORE_GL_CALL;
2511 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
2512 mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
2513 AFTER_GL_CALL;
2516 void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
2518 BEFORE_GL_CALL;
2519 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
2520 mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
2521 AFTER_GL_CALL;
2524 void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
2526 BEFORE_GL_CALL;
2527 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
2528 mSymbols.fGetIntegeri_v(param, index, values);
2529 AFTER_GL_CALL;
2533 // -----------------------------------------------------------------------------
2534 // Package XXX_vertex_array_object
2535 public:
2536 void fBindVertexArray(GLuint array)
2538 BEFORE_GL_CALL;
2539 ASSERT_SYMBOL_PRESENT(fBindVertexArray);
2540 mSymbols.fBindVertexArray(array);
2541 AFTER_GL_CALL;
2544 void fDeleteVertexArrays(GLsizei n, const GLuint *arrays)
2546 BEFORE_GL_CALL;
2547 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
2548 mSymbols.fDeleteVertexArrays(n, arrays);
2549 AFTER_GL_CALL;
2552 void fGenVertexArrays(GLsizei n, GLuint *arrays)
2554 BEFORE_GL_CALL;
2555 ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
2556 mSymbols.fGenVertexArrays(n, arrays);
2557 AFTER_GL_CALL;
2560 realGLboolean fIsVertexArray(GLuint array)
2562 BEFORE_GL_CALL;
2563 ASSERT_SYMBOL_PRESENT(fIsVertexArray);
2564 realGLboolean ret = mSymbols.fIsVertexArray(array);
2565 AFTER_GL_CALL;
2566 return ret;
2569 // -----------------------------------------------------------------------------
2570 // Extension NV_fence
2571 public:
2572 void fGenFences(GLsizei n, GLuint* fences)
2574 ASSERT_SYMBOL_PRESENT(fGenFences);
2575 BEFORE_GL_CALL;
2576 mSymbols.fGenFences(n, fences);
2577 AFTER_GL_CALL;
2580 void fDeleteFences(GLsizei n, const GLuint* fences)
2582 ASSERT_SYMBOL_PRESENT(fDeleteFences);
2583 BEFORE_GL_CALL;
2584 mSymbols.fDeleteFences(n, fences);
2585 AFTER_GL_CALL;
2588 void fSetFence(GLuint fence, GLenum condition)
2590 ASSERT_SYMBOL_PRESENT(fSetFence);
2591 BEFORE_GL_CALL;
2592 mSymbols.fSetFence(fence, condition);
2593 AFTER_GL_CALL;
2596 realGLboolean fTestFence(GLuint fence)
2598 ASSERT_SYMBOL_PRESENT(fTestFence);
2599 BEFORE_GL_CALL;
2600 realGLboolean ret = mSymbols.fTestFence(fence);
2601 AFTER_GL_CALL;
2602 return ret;
2605 void fFinishFence(GLuint fence)
2607 ASSERT_SYMBOL_PRESENT(fFinishFence);
2608 BEFORE_GL_CALL;
2609 mSymbols.fFinishFence(fence);
2610 AFTER_GL_CALL;
2613 realGLboolean fIsFence(GLuint fence)
2615 ASSERT_SYMBOL_PRESENT(fIsFence);
2616 BEFORE_GL_CALL;
2617 realGLboolean ret = mSymbols.fIsFence(fence);
2618 AFTER_GL_CALL;
2619 return ret;
2622 void fGetFenceiv(GLuint fence, GLenum pname, GLint* params)
2624 ASSERT_SYMBOL_PRESENT(fGetFenceiv);
2625 BEFORE_GL_CALL;
2626 mSymbols.fGetFenceiv(fence, pname, params);
2627 AFTER_GL_CALL;
2631 // -----------------------------------------------------------------------------
2632 // Constructor
2633 protected:
2634 explicit GLContext(const SurfaceCaps& caps,
2635 GLContext* sharedContext = nullptr,
2636 bool isOffscreen = false);
2639 // -----------------------------------------------------------------------------
2640 // Destructor
2641 public:
2642 virtual ~GLContext();
2645 // -----------------------------------------------------------------------------
2646 // Everything that isn't standard GL APIs
2647 protected:
2648 typedef gfx::SurfaceFormat SurfaceFormat;
2650 virtual bool MakeCurrentImpl(bool aForce) = 0;
2652 public:
2653 #ifdef DEBUG
2654 static void StaticInit() {
2655 PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
2657 #endif
2659 bool MakeCurrent(bool aForce = false) {
2660 if (IsDestroyed()) {
2661 return false;
2663 #ifdef DEBUG
2664 PR_SetThreadPrivate(sCurrentGLContextTLS, this);
2666 // XXX this assertion is disabled because it's triggering on Mac;
2667 // we need to figure out why and reenable it.
2668 #if 0
2669 // IsOwningThreadCurrent is a bit of a misnomer;
2670 // the "owning thread" is the creation thread,
2671 // and the only thread that can own this. We don't
2672 // support contexts used on multiple threads.
2673 NS_ASSERTION(IsOwningThreadCurrent(),
2674 "MakeCurrent() called on different thread than this context was created on!");
2675 #endif
2676 #endif
2677 return MakeCurrentImpl(aForce);
2680 virtual bool Init() = 0;
2682 virtual bool SetupLookupFunction() = 0;
2684 virtual void ReleaseSurface() {}
2686 // Mark this context as destroyed. This will nullptr out all
2687 // the GL function pointers!
2688 void MarkDestroyed();
2690 bool IsDestroyed() {
2691 // MarkDestroyed will mark all these as null.
2692 return mSymbols.fUseProgram == nullptr;
2695 GLContext *GetSharedContext() { return mSharedContext; }
2698 * Returns true if the thread on which this context was created is the currently
2699 * executing thread.
2701 bool IsOwningThreadCurrent();
2703 static void PlatformStartup();
2705 public:
2707 * If this context wraps a double-buffered target, swap the back
2708 * and front buffers. It should be assumed that after a swap, the
2709 * contents of the new back buffer are undefined.
2711 virtual bool SwapBuffers() { return false; }
2714 * Defines a two-dimensional texture image for context target surface
2716 virtual bool BindTexImage() { return false; }
2718 * Releases a color buffer that is being used as a texture
2720 virtual bool ReleaseTexImage() { return false; }
2722 // Before reads from offscreen texture
2723 void GuaranteeResolve();
2726 * Resize the current offscreen buffer. Returns true on success.
2727 * If it returns false, the context should be treated as unusable
2728 * and should be recreated. After the resize, the viewport is not
2729 * changed; glViewport should be called as appropriate.
2731 * Only valid if IsOffscreen() returns true.
2733 bool ResizeOffscreen(const gfx::IntSize& size) {
2734 return ResizeScreenBuffer(size);
2738 * Return size of this offscreen context.
2740 * Only valid if IsOffscreen() returns true.
2742 const gfx::IntSize& OffscreenSize() const;
2744 void BindFB(GLuint fb) {
2745 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
2746 MOZ_ASSERT(!fb || fIsFramebuffer(fb));
2749 void BindDrawFB(GLuint fb) {
2750 fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
2753 void BindReadFB(GLuint fb) {
2754 fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
2757 GLuint GetDrawFB() {
2758 if (mScreen)
2759 return mScreen->GetDrawFB();
2761 GLuint ret = 0;
2762 GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
2763 return ret;
2766 GLuint GetReadFB() {
2767 if (mScreen)
2768 return mScreen->GetReadFB();
2770 GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit)
2771 ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
2772 : LOCAL_GL_FRAMEBUFFER_BINDING;
2774 GLuint ret = 0;
2775 GetUIntegerv(bindEnum, &ret);
2776 return ret;
2779 GLuint GetFB() {
2780 if (mScreen) {
2781 // This has a very important extra assert that checks that we're
2782 // not accidentally ignoring a situation where the draw and read
2783 // FBs differ.
2784 return mScreen->GetFB();
2787 GLuint ret = 0;
2788 GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
2789 return ret;
2792 private:
2793 void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
2794 switch (precisiontype) {
2795 case LOCAL_GL_LOW_FLOAT:
2796 case LOCAL_GL_MEDIUM_FLOAT:
2797 case LOCAL_GL_HIGH_FLOAT:
2798 // Assume IEEE 754 precision
2799 range[0] = 127;
2800 range[1] = 127;
2801 *precision = 23;
2802 break;
2803 case LOCAL_GL_LOW_INT:
2804 case LOCAL_GL_MEDIUM_INT:
2805 case LOCAL_GL_HIGH_INT:
2806 // Some (most) hardware only supports single-precision floating-point numbers,
2807 // which can accurately represent integers up to +/-16777216
2808 range[0] = 24;
2809 range[1] = 24;
2810 *precision = 0;
2811 break;
2815 public:
2817 void ForceDirtyScreen();
2818 void CleanDirtyScreen();
2820 virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
2822 virtual bool RenewSurface() { return false; }
2824 // Shared code for GL extensions and GLX extensions.
2825 static bool ListHasExtension(const GLubyte *extensions,
2826 const char *extension);
2828 GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
2830 public:
2831 std::map<GLuint, SharedSurface*> mFBOMapping;
2833 enum {
2834 DebugEnabled = 1 << 0,
2835 DebugTrace = 1 << 1,
2836 DebugAbortOnError = 1 << 2
2839 static uint32_t sDebugMode;
2841 static uint32_t DebugMode() {
2842 #ifdef DEBUG
2843 return sDebugMode;
2844 #else
2845 return 0;
2846 #endif
2849 protected:
2850 nsRefPtr<GLContext> mSharedContext;
2852 // The thread id which this context was created.
2853 PlatformThreadId mOwningThreadId;
2855 GLContextSymbols mSymbols;
2857 #ifdef DEBUG
2858 // GLDebugMode will check that we don't send call
2859 // to a GLContext that isn't current on the current
2860 // thread.
2861 // Store the current context when binding to thread local
2862 // storage to support DebugMode on an arbitrary thread.
2863 static unsigned sCurrentGLContextTLS;
2864 #endif
2866 UniquePtr<GLBlitHelper> mBlitHelper;
2867 UniquePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
2868 UniquePtr<GLReadTexImageHelper> mReadTexImageHelper;
2870 public:
2871 GLBlitHelper* BlitHelper();
2872 GLBlitTextureImageHelper* BlitTextureImageHelper();
2873 GLReadTexImageHelper* ReadTexImageHelper();
2875 // Assumes shares are created by all sharing with the same global context.
2876 bool SharesWith(const GLContext* other) const {
2877 MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
2878 MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
2879 MOZ_ASSERT(!this->mSharedContext ||
2880 !other->mSharedContext ||
2881 this->mSharedContext == other->mSharedContext);
2883 const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
2884 : this;
2885 const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
2886 : other;
2888 return thisShared == otherShared;
2891 bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps) {
2892 if (!CreateScreenBuffer(size, caps))
2893 return false;
2895 MakeCurrent();
2896 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
2897 fScissor(0, 0, size.width, size.height);
2898 fViewport(0, 0, size.width, size.height);
2900 mCaps = mScreen->mCaps;
2901 if (mCaps.any)
2902 DetermineCaps();
2904 UpdateGLFormats(mCaps);
2905 UpdatePixelFormat();
2907 return true;
2910 protected:
2911 // Note that it does -not- clear the resized buffers.
2912 bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
2913 if (!IsOffscreenSizeAllowed(size))
2914 return false;
2916 SurfaceCaps tryCaps = caps;
2917 if (tryCaps.antialias) {
2918 // AA path
2919 if (CreateScreenBufferImpl(size, tryCaps))
2920 return true;
2922 NS_WARNING("CreateScreenBuffer failed to initialize an AA context! Falling back to no AA...");
2923 tryCaps.antialias = false;
2925 MOZ_ASSERT(!tryCaps.antialias);
2927 if (CreateScreenBufferImpl(size, tryCaps))
2928 return true;
2930 NS_WARNING("CreateScreenBuffer failed to initialize non-AA context!");
2931 return false;
2934 bool CreateScreenBufferImpl(const gfx::IntSize& size,
2935 const SurfaceCaps& caps);
2937 public:
2938 bool ResizeScreenBuffer(const gfx::IntSize& size);
2940 protected:
2941 SurfaceCaps mCaps;
2942 nsAutoPtr<GLFormats> mGLFormats;
2943 nsAutoPtr<PixelBufferFormat> mPixelFormat;
2945 public:
2946 void DetermineCaps();
2947 const SurfaceCaps& Caps() const {
2948 return mCaps;
2951 // Only varies based on bpp16 and alpha.
2952 GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
2953 void UpdateGLFormats(const SurfaceCaps& caps) {
2954 mGLFormats = new GLFormats(ChooseGLFormats(caps));
2957 const GLFormats& GetGLFormats() const {
2958 MOZ_ASSERT(mGLFormats);
2959 return *mGLFormats;
2962 PixelBufferFormat QueryPixelFormat();
2963 void UpdatePixelFormat();
2965 const PixelBufferFormat& GetPixelFormat() const {
2966 MOZ_ASSERT(mPixelFormat);
2967 return *mPixelFormat;
2970 bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
2972 // Does not check completeness.
2973 void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
2974 GLuint depthRB, GLuint stencilRB,
2975 GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
2977 // Passing null is fine if the value you'd get is 0.
2978 bool AssembleOffscreenFBs(const GLuint colorMSRB,
2979 const GLuint depthRB,
2980 const GLuint stencilRB,
2981 const GLuint texture,
2982 GLuint* drawFB,
2983 GLuint* readFB);
2985 protected:
2986 friend class GLScreenBuffer;
2987 UniquePtr<GLScreenBuffer> mScreen;
2989 void DestroyScreenBuffer();
2991 SharedSurface* mLockedSurface;
2993 public:
2994 void LockSurface(SharedSurface* surf) {
2995 MOZ_ASSERT(!mLockedSurface);
2996 mLockedSurface = surf;
2999 void UnlockSurface(SharedSurface* surf) {
3000 MOZ_ASSERT(mLockedSurface == surf);
3001 mLockedSurface = nullptr;
3004 SharedSurface* GetLockedSurface() const {
3005 return mLockedSurface;
3008 bool IsOffscreen() const {
3009 return mScreen;
3012 GLScreenBuffer* Screen() const {
3013 return mScreen.get();
3016 bool PublishFrame();
3017 SharedSurface* RequestFrame();
3019 /* Clear to transparent black, with 0 depth and stencil,
3020 * while preserving current ClearColor etc. values.
3021 * Useful for resizing offscreen buffers.
3023 void ClearSafely();
3025 bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
3027 protected:
3028 nsRefPtr<TextureGarbageBin> mTexGarbageBin;
3030 public:
3031 TextureGarbageBin* TexGarbageBin() {
3032 MOZ_ASSERT(mTexGarbageBin);
3033 return mTexGarbageBin;
3036 void EmptyTexGarbageBin();
3038 bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
3040 protected:
3041 bool InitWithPrefix(const char *prefix, bool trygl);
3043 void InitExtensions();
3045 GLint mViewportRect[4];
3046 GLint mScissorRect[4];
3048 GLint mMaxTextureSize;
3049 GLint mMaxCubeMapTextureSize;
3050 GLint mMaxTextureImageSize;
3051 GLint mMaxRenderbufferSize;
3052 GLint mMaxViewportDims[2];
3053 GLsizei mMaxSamples;
3054 bool mNeedsTextureSizeChecks;
3055 bool mWorkAroundDriverBugs;
3057 bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
3058 if (mNeedsTextureSizeChecks) {
3059 // some drivers incorrectly handle some large texture sizes that are below the
3060 // max texture size that they report. So we check ourselves against our own values
3061 // (mMax[CubeMap]TextureSize).
3062 // see bug 737182 for Mac Intel 2D textures
3063 // see bug 684882 for Mac Intel cube map textures
3064 // see bug 814716 for Mesa Nouveau
3065 GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
3066 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
3067 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3068 ? mMaxCubeMapTextureSize
3069 : mMaxTextureSize;
3070 return width <= maxSize && height <= maxSize;
3072 return true;
3076 public:
3078 void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
3079 if (mViewportRect[0] == x &&
3080 mViewportRect[1] == y &&
3081 mViewportRect[2] == width &&
3082 mViewportRect[3] == height)
3084 return;
3086 mViewportRect[0] = x;
3087 mViewportRect[1] = y;
3088 mViewportRect[2] = width;
3089 mViewportRect[3] = height;
3090 BEFORE_GL_CALL;
3091 mSymbols.fViewport(x, y, width, height);
3092 AFTER_GL_CALL;
3095 #undef ASSERT_SYMBOL_PRESENT
3097 #ifdef DEBUG
3098 void CreatedProgram(GLContext *aOrigin, GLuint aName);
3099 void CreatedShader(GLContext *aOrigin, GLuint aName);
3100 void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
3101 void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
3102 void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
3103 void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
3104 void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
3105 void DeletedProgram(GLContext *aOrigin, GLuint aName);
3106 void DeletedShader(GLContext *aOrigin, GLuint aName);
3107 void DeletedBuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
3108 void DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
3109 void DeletedTextures(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
3110 void DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
3111 void DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
3113 void SharedContextDestroyed(GLContext *aChild);
3114 void ReportOutstandingNames();
3116 struct NamedResource {
3117 NamedResource()
3118 : origin(nullptr), name(0), originDeleted(false)
3121 NamedResource(GLContext *aOrigin, GLuint aName)
3122 : origin(aOrigin), name(aName), originDeleted(false)
3125 GLContext *origin;
3126 GLuint name;
3127 bool originDeleted;
3129 // for sorting
3130 bool operator<(const NamedResource& aOther) const {
3131 if (intptr_t(origin) < intptr_t(aOther.origin))
3132 return true;
3133 if (name < aOther.name)
3134 return true;
3135 return false;
3137 bool operator==(const NamedResource& aOther) const {
3138 return origin == aOther.origin &&
3139 name == aOther.name &&
3140 originDeleted == aOther.originDeleted;
3144 nsTArray<NamedResource> mTrackedPrograms;
3145 nsTArray<NamedResource> mTrackedShaders;
3146 nsTArray<NamedResource> mTrackedTextures;
3147 nsTArray<NamedResource> mTrackedFramebuffers;
3148 nsTArray<NamedResource> mTrackedRenderbuffers;
3149 nsTArray<NamedResource> mTrackedBuffers;
3150 nsTArray<NamedResource> mTrackedQueries;
3151 #endif
3154 bool DoesStringMatch(const char* aString, const char *aWantedString);
3157 } /* namespace gl */
3158 } /* namespace mozilla */
3160 #endif /* GLCONTEXT_H_ */