Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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>
16 #ifdef DEBUG
17 #include <string.h>
18 #endif
20 #ifdef WIN32
21 #include <windows.h>
22 #endif
24 #ifdef GetClassName
25 #undef GetClassName
26 #endif
28 #include "GLDefs.h"
29 #include "GLLibraryLoader.h"
30 #include "gfx3DMatrix.h"
31 #include "nsISupportsImpl.h"
32 #include "plstr.h"
33 #include "nsDataHashtable.h"
34 #include "nsHashKeys.h"
35 #include "nsAutoPtr.h"
36 #include "GLContextTypes.h"
37 #include "GLTextureImage.h"
38 #include "SurfaceTypes.h"
39 #include "GLScreenBuffer.h"
40 #include "GLContextSymbols.h"
41 #include "mozilla/GenericRefCounted.h"
42 #include "mozilla/Scoped.h"
43 #include "gfx2DGlue.h"
45 #ifdef DEBUG
46 #define MOZ_ENABLE_GL_TRACKING 1
47 #endif
49 class nsIntRegion;
50 class nsIRunnable;
51 class nsIThread;
53 namespace android {
54 class GraphicBuffer;
55 }
57 namespace mozilla {
58 namespace gfx {
59 class SourceSurface;
60 class DataSourceSurface;
61 struct SurfaceCaps;
62 }
64 namespace gl {
65 class GLContext;
66 class GLLibraryEGL;
67 class GLScreenBuffer;
68 class TextureGarbageBin;
69 class GLBlitHelper;
70 class GLBlitTextureImageHelper;
71 class GLReadTexImageHelper;
72 class SharedSurface_GL;
73 }
75 namespace layers {
76 class ColorTextureLayerProgram;
77 }
78 }
80 namespace mozilla {
81 namespace gl {
83 MOZ_BEGIN_ENUM_CLASS(GLFeature)
84 bind_buffer_offset,
85 blend_minmax,
86 depth_texture,
87 draw_buffers,
88 draw_instanced,
89 draw_range_elements,
90 element_index_uint,
91 ES2_compatibility,
92 ES3_compatibility,
93 frag_color_float,
94 frag_depth,
95 framebuffer_blit,
96 framebuffer_multisample,
97 framebuffer_object,
98 get_query_object_iv,
99 instanced_arrays,
100 instanced_non_arrays,
101 occlusion_query,
102 occlusion_query_boolean,
103 occlusion_query2,
104 packed_depth_stencil,
105 query_objects,
106 renderbuffer_color_float,
107 renderbuffer_color_half_float,
108 robustness,
109 sRGB,
110 standard_derivatives,
111 texture_float,
112 texture_float_linear,
113 texture_half_float,
114 texture_half_float_linear,
115 texture_non_power_of_two,
116 transform_feedback,
117 vertex_array_object,
118 EnumMax
119 MOZ_END_ENUM_CLASS(GLFeature)
121 MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
122 Unknown = 0,
123 OpenGL, // only for IsAtLeast's <profile> parameter
124 OpenGLCore,
125 OpenGLCompatibility,
126 OpenGLES
127 MOZ_END_ENUM_CLASS(ContextProfile)
129 MOZ_BEGIN_ENUM_CLASS(GLVendor)
130 Intel,
131 NVIDIA,
132 ATI,
133 Qualcomm,
134 Imagination,
135 Nouveau,
136 Vivante,
137 VMware,
138 Other
139 MOZ_END_ENUM_CLASS(GLVendor)
141 MOZ_BEGIN_ENUM_CLASS(GLRenderer)
142 Adreno200,
143 Adreno205,
144 AdrenoTM205,
145 AdrenoTM320,
146 SGX530,
147 SGX540,
148 Tegra,
149 AndroidEmulator,
150 GalliumLlvmpipe,
151 Other
152 MOZ_END_ENUM_CLASS(GLRenderer)
154 class GLContext
155 : public GLLibraryLoader
156 , public GenericAtomicRefCounted
157 {
158 // -----------------------------------------------------------------------------
159 // basic enums
160 public:
162 // -----------------------------------------------------------------------------
163 // basic getters
164 public:
166 /**
167 * Returns true if the context is using ANGLE. This should only be overridden
168 * for an ANGLE implementation.
169 */
170 virtual bool IsANGLE() const {
171 return false;
172 }
174 /**
175 * Return true if we are running on a OpenGL core profile context
176 */
177 inline bool IsCoreProfile() const {
178 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
180 return mProfile == ContextProfile::OpenGLCore;
181 }
183 /**
184 * Return true if we are running on a OpenGL compatibility profile context
185 * (legacy profile 2.1 on Max OS X)
186 */
187 inline bool IsCompatibilityProfile() const {
188 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
190 return mProfile == ContextProfile::OpenGLCompatibility;
191 }
193 /**
194 * Return true if the context is a true OpenGL ES context or an ANGLE context
195 */
196 inline bool IsGLES() const {
197 MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
199 return mProfile == ContextProfile::OpenGLES;
200 }
202 static const char* GetProfileName(ContextProfile profile)
203 {
204 switch (profile)
205 {
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;
216 }
218 MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile");
219 return "OpenGL unknown profile";
220 }
222 /**
223 * Return true if we are running on a OpenGL core profile context
224 */
225 const char* ProfileString() const {
226 return GetProfileName(mProfile);
227 }
229 /**
230 * Return true if the context is compatible with given parameters
231 *
232 * IsAtLeast(ContextProfile::OpenGL, N) is exactly same as
233 * IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N)
234 */
235 inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
236 {
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;
243 }
245 if (profile == ContextProfile::OpenGL) {
246 return profile == ContextProfile::OpenGLCore ||
247 profile == ContextProfile::OpenGLCompatibility;
248 }
250 return profile == mProfile;
251 }
253 /**
254 * Return the version of the context.
255 * Example :
256 * If this a OpenGL 2.1, that will return 210
257 */
258 inline unsigned int Version() const {
259 return mVersion;
260 }
262 const char* VersionString() const {
263 return mVersionString.get();
264 }
266 GLVendor Vendor() const {
267 return mVendor;
268 }
270 GLRenderer Renderer() const {
271 return mRenderer;
272 }
274 bool IsContextLost() const {
275 return mContextLost;
276 }
278 /**
279 * If this context is double-buffered, returns TRUE.
280 */
281 virtual bool IsDoubleBuffered() const {
282 return false;
283 }
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;
296 /**
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.
299 */
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;
314 }
317 // -----------------------------------------------------------------------------
318 // Extensions management
319 /**
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).
324 */
325 public:
327 /**
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.
333 */
334 enum GLExtensions {
335 EXT_framebuffer_object,
336 ARB_framebuffer_object,
337 ARB_texture_rectangle,
338 EXT_bgra,
339 EXT_texture_format_BGRA8888,
340 OES_depth24,
341 OES_depth32,
342 OES_stencil8,
343 OES_texture_npot,
344 ARB_depth_texture,
345 OES_depth_texture,
346 OES_packed_depth_stencil,
347 IMG_read_format,
348 EXT_read_format_bgra,
349 APPLE_client_storage,
350 APPLE_texture_range,
351 ARB_texture_non_power_of_two,
352 ARB_pixel_buffer_object,
353 ARB_ES2_compatibility,
354 ARB_ES3_compatibility,
355 OES_texture_float,
356 OES_texture_float_linear,
357 ARB_texture_float,
358 OES_texture_half_float,
359 OES_texture_half_float_linear,
360 NV_half_float,
361 EXT_color_buffer_float,
362 EXT_color_buffer_half_float,
363 ARB_color_buffer_float,
364 EXT_unpack_subimage,
365 OES_standard_derivatives,
366 EXT_texture_filter_anisotropic,
367 EXT_texture_compression_s3tc,
368 EXT_texture_compression_dxt1,
369 ANGLE_texture_compression_dxt3,
370 ANGLE_texture_compression_dxt5,
371 AMD_compressed_ATC_texture,
372 IMG_texture_compression_pvrtc,
373 EXT_framebuffer_blit,
374 ANGLE_framebuffer_blit,
375 EXT_framebuffer_multisample,
376 ANGLE_framebuffer_multisample,
377 OES_rgb8_rgba8,
378 ARB_robustness,
379 EXT_robustness,
380 ARB_sync,
381 OES_EGL_image,
382 OES_EGL_sync,
383 OES_EGL_image_external,
384 EXT_packed_depth_stencil,
385 OES_element_index_uint,
386 OES_vertex_array_object,
387 ARB_vertex_array_object,
388 APPLE_vertex_array_object,
389 ARB_draw_buffers,
390 EXT_draw_buffers,
391 EXT_gpu_shader4,
392 EXT_blend_minmax,
393 ARB_draw_instanced,
394 EXT_draw_instanced,
395 NV_draw_instanced,
396 ARB_instanced_arrays,
397 NV_instanced_arrays,
398 ANGLE_instanced_arrays,
399 EXT_occlusion_query_boolean,
400 ARB_occlusion_query2,
401 EXT_transform_feedback,
402 NV_transform_feedback,
403 ANGLE_depth_texture,
404 EXT_sRGB,
405 EXT_texture_sRGB,
406 ARB_framebuffer_sRGB,
407 EXT_framebuffer_sRGB,
408 KHR_debug,
409 ARB_half_float_pixel,
410 EXT_frag_depth,
411 OES_compressed_ETC1_RGB8_texture,
412 EXT_draw_range_elements,
413 Extensions_Max,
414 Extensions_End
415 };
417 bool IsExtensionSupported(GLExtensions aKnownExtension) const {
418 return mAvailableExtensions[aKnownExtension];
419 }
421 void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
422 mAvailableExtensions[aKnownExtension] = 0;
423 }
425 void MarkExtensionSupported(GLExtensions aKnownExtension) {
426 mAvailableExtensions[aKnownExtension] = 1;
427 }
430 public:
432 template<size_t N>
433 static void InitializeExtensionsBitSet(std::bitset<N>& extensionsBitset, const char* extStr, const char** extList, bool verbose = false)
434 {
435 char* exts = ::strdup(extStr);
437 if (verbose)
438 printf_stderr("Extensions: %s\n", exts);
440 char* cur = exts;
441 bool done = false;
442 while (!done) {
443 char* space = strchr(cur, ' ');
444 if (space) {
445 *space = '\0';
446 } else {
447 done = true;
448 }
450 for (int i = 0; extList[i]; ++i) {
451 if (PL_strcasecmp(cur, extList[i]) == 0) {
452 if (verbose)
453 printf_stderr("Found extension %s\n", cur);
454 extensionsBitset[i] = true;
455 }
456 }
458 cur = space + 1;
459 }
461 free(exts);
462 }
465 protected:
466 std::bitset<Extensions_Max> mAvailableExtensions;
469 // -----------------------------------------------------------------------------
470 // Feature queries
471 /*
472 * This mecahnism introduces a new way to check if a OpenGL feature is
473 * supported, regardless of whether it is supported by an extension or natively
474 * by the context version/profile
475 */
476 public:
477 bool IsSupported(GLFeature feature) const {
478 return mAvailableFeatures[size_t(feature)];
479 }
481 static const char* GetFeatureName(GLFeature feature);
484 private:
485 std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
487 /**
488 * Init features regarding OpenGL extension and context version and profile
489 */
490 void InitFeatures();
492 /**
493 * Mark the feature and associated extensions as unsupported
494 */
495 void MarkUnsupported(GLFeature feature);
497 // -----------------------------------------------------------------------------
498 // Robustness handling
499 public:
501 bool HasRobustness() const {
502 return mHasRobustness;
503 }
505 /**
506 * The derived class is expected to provide information on whether or not it
507 * supports robustness.
508 */
509 virtual bool SupportsRobustness() const = 0;
512 private:
513 bool mHasRobustness;
516 // -----------------------------------------------------------------------------
517 // Error handling
518 public:
520 static const char* GLErrorToString(GLenum aError)
521 {
522 switch (aError) {
523 case LOCAL_GL_INVALID_ENUM:
524 return "GL_INVALID_ENUM";
525 case LOCAL_GL_INVALID_VALUE:
526 return "GL_INVALID_VALUE";
527 case LOCAL_GL_INVALID_OPERATION:
528 return "GL_INVALID_OPERATION";
529 case LOCAL_GL_STACK_OVERFLOW:
530 return "GL_STACK_OVERFLOW";
531 case LOCAL_GL_STACK_UNDERFLOW:
532 return "GL_STACK_UNDERFLOW";
533 case LOCAL_GL_OUT_OF_MEMORY:
534 return "GL_OUT_OF_MEMORY";
535 case LOCAL_GL_TABLE_TOO_LARGE:
536 return "GL_TABLE_TOO_LARGE";
537 case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
538 return "GL_INVALID_FRAMEBUFFER_OPERATION";
539 default:
540 return "";
541 }
542 }
545 /** \returns the first GL error, and guarantees that all GL error flags are cleared,
546 * i.e. that a subsequent GetError call will return NO_ERROR
547 */
548 GLenum GetAndClearError()
549 {
550 // the first error is what we want to return
551 GLenum error = fGetError();
553 if (error) {
554 // clear all pending errors
555 while(fGetError()) {}
556 }
558 return error;
559 }
562 /*** In GL debug mode, we completely override glGetError ***/
564 GLenum fGetError()
565 {
566 #ifdef DEBUG
567 // debug mode ends up eating the error in AFTER_GL_CALL
568 if (DebugMode()) {
569 GLenum err = mGLError;
570 mGLError = LOCAL_GL_NO_ERROR;
571 return err;
572 }
573 #endif // DEBUG
575 return mSymbols.fGetError();
576 }
579 #ifdef DEBUG
580 private:
582 GLenum mGLError;
583 #endif // DEBUG
586 // -----------------------------------------------------------------------------
587 // MOZ_GL_DEBUG implementation
588 private:
590 #undef BEFORE_GL_CALL
591 #undef AFTER_GL_CALL
593 #ifdef MOZ_ENABLE_GL_TRACKING
595 #ifndef MOZ_FUNCTION_NAME
596 # ifdef __GNUC__
597 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
598 # elif defined(_MSC_VER)
599 # define MOZ_FUNCTION_NAME __FUNCTION__
600 # else
601 # define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name.
602 # endif
603 #endif
605 void BeforeGLCall(const char* glFunction)
606 {
607 MOZ_ASSERT(IsCurrent());
608 if (DebugMode()) {
609 GLContext *currentGLContext = nullptr;
611 currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
613 if (DebugMode() & DebugTrace)
614 printf_stderr("[gl:%p] > %s\n", this, glFunction);
615 if (this != currentGLContext) {
616 printf_stderr("Fatal: %s called on non-current context %p. "
617 "The current context for this thread is %p.\n",
618 glFunction, this, currentGLContext);
619 NS_ABORT();
620 }
621 }
622 }
624 void AfterGLCall(const char* glFunction)
625 {
626 if (DebugMode()) {
627 // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
628 // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
629 // tend to be meaningless
630 mSymbols.fFinish();
631 mGLError = mSymbols.fGetError();
632 if (DebugMode() & DebugTrace)
633 printf_stderr("[gl:%p] < %s [0x%04x]\n", this, glFunction, mGLError);
634 if (mGLError != LOCAL_GL_NO_ERROR) {
635 printf_stderr("GL ERROR: %s generated GL error %s(0x%04x)\n",
636 glFunction,
637 GLErrorToString(mGLError),
638 mGLError);
639 if (DebugMode() & DebugAbortOnError)
640 NS_ABORT();
641 }
642 }
643 }
645 GLContext *TrackingContext()
646 {
647 GLContext *tip = this;
648 while (tip->mSharedContext)
649 tip = tip->mSharedContext;
650 return tip;
651 }
653 #define BEFORE_GL_CALL \
654 do { \
655 BeforeGLCall(MOZ_FUNCTION_NAME); \
656 } while (0)
658 #define AFTER_GL_CALL \
659 do { \
660 AfterGLCall(MOZ_FUNCTION_NAME); \
661 } while (0)
663 #define TRACKING_CONTEXT(a) \
664 do { \
665 TrackingContext()->a; \
666 } while (0)
668 #else // ifdef DEBUG
670 #define BEFORE_GL_CALL do { } while (0)
671 #define AFTER_GL_CALL do { } while (0)
672 #define TRACKING_CONTEXT(a) do {} while (0)
674 #endif // ifdef DEBUG
676 #define ASSERT_SYMBOL_PRESENT(func) \
677 do {\
678 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
679 if (MOZ_UNLIKELY(!mSymbols.func)) {\
680 printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
681 MOZ_CRASH();\
682 }\
683 } while (0)
685 // Do whatever setup is necessary to draw to our offscreen FBO, if it's
686 // bound.
687 void BeforeGLDrawCall() {
688 }
690 // Do whatever tear-down is necessary after drawing to our offscreen FBO,
691 // if it's bound.
692 void AfterGLDrawCall()
693 {
694 if (mScreen)
695 mScreen->AfterDrawCall();
696 }
698 // Do whatever setup is necessary to read from our offscreen FBO, if it's
699 // bound.
700 void BeforeGLReadCall()
701 {
702 if (mScreen)
703 mScreen->BeforeReadCall();
704 }
706 // Do whatever tear-down is necessary after reading from our offscreen FBO,
707 // if it's bound.
708 void AfterGLReadCall() {
709 }
712 // -----------------------------------------------------------------------------
713 // GL official entry points
714 public:
716 void fActiveTexture(GLenum texture) {
717 BEFORE_GL_CALL;
718 mSymbols.fActiveTexture(texture);
719 AFTER_GL_CALL;
720 }
722 void fAttachShader(GLuint program, GLuint shader) {
723 BEFORE_GL_CALL;
724 mSymbols.fAttachShader(program, shader);
725 AFTER_GL_CALL;
726 }
728 void fBeginQuery(GLenum target, GLuint id) {
729 BEFORE_GL_CALL;
730 ASSERT_SYMBOL_PRESENT(fBeginQuery);
731 mSymbols.fBeginQuery(target, id);
732 AFTER_GL_CALL;
733 }
735 void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
736 BEFORE_GL_CALL;
737 mSymbols.fBindAttribLocation(program, index, name);
738 AFTER_GL_CALL;
739 }
741 void fBindBuffer(GLenum target, GLuint buffer) {
742 BEFORE_GL_CALL;
743 mSymbols.fBindBuffer(target, buffer);
744 AFTER_GL_CALL;
745 }
747 void fBindFramebuffer(GLenum target, GLuint framebuffer) {
748 if (!mScreen) {
749 raw_fBindFramebuffer(target, framebuffer);
750 return;
751 }
753 switch (target) {
754 case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
755 mScreen->BindDrawFB(framebuffer);
756 return;
758 case LOCAL_GL_READ_FRAMEBUFFER_EXT:
759 mScreen->BindReadFB(framebuffer);
760 return;
762 case LOCAL_GL_FRAMEBUFFER:
763 mScreen->BindFB(framebuffer);
764 return;
766 default:
767 // Nothing we care about, likely an error.
768 break;
769 }
771 raw_fBindFramebuffer(target, framebuffer);
772 }
774 void fBindTexture(GLenum target, GLuint texture) {
775 BEFORE_GL_CALL;
776 mSymbols.fBindTexture(target, texture);
777 AFTER_GL_CALL;
778 }
780 void fBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
781 BEFORE_GL_CALL;
782 mSymbols.fBlendColor(red, green, blue, alpha);
783 AFTER_GL_CALL;
784 }
786 void fBlendEquation(GLenum mode) {
787 BEFORE_GL_CALL;
788 mSymbols.fBlendEquation(mode);
789 AFTER_GL_CALL;
790 }
792 void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
793 BEFORE_GL_CALL;
794 mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
795 AFTER_GL_CALL;
796 }
798 void fBlendFunc(GLenum sfactor, GLenum dfactor) {
799 BEFORE_GL_CALL;
800 mSymbols.fBlendFunc(sfactor, dfactor);
801 AFTER_GL_CALL;
802 }
804 void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
805 BEFORE_GL_CALL;
806 mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
807 AFTER_GL_CALL;
808 }
810 private:
811 void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
812 BEFORE_GL_CALL;
813 mSymbols.fBufferData(target, size, data, usage);
814 AFTER_GL_CALL;
815 }
817 public:
818 void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
819 raw_fBufferData(target, size, data, usage);
821 // bug 744888
822 if (WorkAroundDriverBugs() &&
823 !data &&
824 Vendor() == GLVendor::NVIDIA)
825 {
826 char c = 0;
827 fBufferSubData(target, size-1, 1, &c);
828 }
829 }
831 void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
832 BEFORE_GL_CALL;
833 mSymbols.fBufferSubData(target, offset, size, data);
834 AFTER_GL_CALL;
835 }
837 private:
838 void raw_fClear(GLbitfield mask) {
839 BEFORE_GL_CALL;
840 mSymbols.fClear(mask);
841 AFTER_GL_CALL;
842 }
844 public:
845 void fClear(GLbitfield mask) {
846 BeforeGLDrawCall();
847 raw_fClear(mask);
848 AfterGLDrawCall();
849 }
851 void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
852 BEFORE_GL_CALL;
853 mSymbols.fClearColor(r, g, b, a);
854 AFTER_GL_CALL;
855 }
857 void fClearStencil(GLint s) {
858 BEFORE_GL_CALL;
859 mSymbols.fClearStencil(s);
860 AFTER_GL_CALL;
861 }
863 void fClientActiveTexture(GLenum texture) {
864 BEFORE_GL_CALL;
865 mSymbols.fClientActiveTexture(texture);
866 AFTER_GL_CALL;
867 }
869 void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
870 BEFORE_GL_CALL;
871 mSymbols.fColorMask(red, green, blue, alpha);
872 AFTER_GL_CALL;
873 }
875 void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *pixels) {
876 BEFORE_GL_CALL;
877 mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
878 AFTER_GL_CALL;
879 }
881 void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) {
882 BEFORE_GL_CALL;
883 mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
884 AFTER_GL_CALL;
885 }
887 void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
888 if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
889 // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
890 // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
891 level = -1;
892 width = -1;
893 height = -1;
894 border = -1;
895 }
897 BeforeGLReadCall();
898 raw_fCopyTexImage2D(target, level, internalformat,
899 x, y, width, height, border);
900 AfterGLReadCall();
901 }
903 void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
904 BeforeGLReadCall();
905 raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
906 x, y, width, height);
907 AfterGLReadCall();
908 }
910 void fCullFace(GLenum mode) {
911 BEFORE_GL_CALL;
912 mSymbols.fCullFace(mode);
913 AFTER_GL_CALL;
914 }
916 void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
917 BEFORE_GL_CALL;
918 ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
919 mSymbols.fDebugMessageCallback(callback, userParam);
920 AFTER_GL_CALL;
921 }
923 void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) {
924 BEFORE_GL_CALL;
925 ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
926 mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
927 AFTER_GL_CALL;
928 }
930 void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
931 BEFORE_GL_CALL;
932 ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
933 mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
934 AFTER_GL_CALL;
935 }
937 void fDetachShader(GLuint program, GLuint shader) {
938 BEFORE_GL_CALL;
939 mSymbols.fDetachShader(program, shader);
940 AFTER_GL_CALL;
941 }
943 void fDepthFunc(GLenum func) {
944 BEFORE_GL_CALL;
945 mSymbols.fDepthFunc(func);
946 AFTER_GL_CALL;
947 }
949 void fDepthMask(realGLboolean flag) {
950 BEFORE_GL_CALL;
951 mSymbols.fDepthMask(flag);
952 AFTER_GL_CALL;
953 }
955 void fDisable(GLenum capability) {
956 BEFORE_GL_CALL;
957 mSymbols.fDisable(capability);
958 AFTER_GL_CALL;
959 }
961 void fDisableClientState(GLenum capability) {
962 BEFORE_GL_CALL;
963 mSymbols.fDisableClientState(capability);
964 AFTER_GL_CALL;
965 }
967 void fDisableVertexAttribArray(GLuint index) {
968 BEFORE_GL_CALL;
969 mSymbols.fDisableVertexAttribArray(index);
970 AFTER_GL_CALL;
971 }
973 void fDrawBuffer(GLenum mode) {
974 BEFORE_GL_CALL;
975 mSymbols.fDrawBuffer(mode);
976 AFTER_GL_CALL;
977 }
979 private:
980 void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
981 BEFORE_GL_CALL;
982 mSymbols.fDrawArrays(mode, first, count);
983 AFTER_GL_CALL;
984 }
986 void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
987 BEFORE_GL_CALL;
988 mSymbols.fDrawElements(mode, count, type, indices);
989 AFTER_GL_CALL;
990 }
992 public:
993 void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
994 BeforeGLDrawCall();
995 raw_fDrawArrays(mode, first, count);
996 AfterGLDrawCall();
997 }
999 void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
1000 BeforeGLDrawCall();
1001 raw_fDrawElements(mode, count, type, indices);
1002 AfterGLDrawCall();
1003 }
1005 void fEnable(GLenum capability) {
1006 BEFORE_GL_CALL;
1007 mSymbols.fEnable(capability);
1008 AFTER_GL_CALL;
1009 }
1011 void fEnableClientState(GLenum capability) {
1012 BEFORE_GL_CALL;
1013 mSymbols.fEnableClientState(capability);
1014 AFTER_GL_CALL;
1015 }
1017 void fEnableVertexAttribArray(GLuint index) {
1018 BEFORE_GL_CALL;
1019 mSymbols.fEnableVertexAttribArray(index);
1020 AFTER_GL_CALL;
1021 }
1023 void fEndQuery(GLenum target) {
1024 BEFORE_GL_CALL;
1025 ASSERT_SYMBOL_PRESENT(fEndQuery);
1026 mSymbols.fEndQuery(target);
1027 AFTER_GL_CALL;
1028 }
1030 void fFinish() {
1031 BEFORE_GL_CALL;
1032 mSymbols.fFinish();
1033 AFTER_GL_CALL;
1034 }
1036 void fFlush() {
1037 BEFORE_GL_CALL;
1038 mSymbols.fFlush();
1039 AFTER_GL_CALL;
1040 }
1042 void fFrontFace(GLenum face) {
1043 BEFORE_GL_CALL;
1044 mSymbols.fFrontFace(face);
1045 AFTER_GL_CALL;
1046 }
1048 void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1049 BEFORE_GL_CALL;
1050 mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
1051 AFTER_GL_CALL;
1052 }
1054 void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1055 BEFORE_GL_CALL;
1056 mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
1057 AFTER_GL_CALL;
1058 }
1060 void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
1061 BEFORE_GL_CALL;
1062 mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
1063 AFTER_GL_CALL;
1064 }
1066 GLint fGetAttribLocation(GLuint program, const GLchar* name) {
1067 BEFORE_GL_CALL;
1068 GLint retval = mSymbols.fGetAttribLocation(program, name);
1069 AFTER_GL_CALL;
1070 return retval;
1071 }
1073 private:
1074 void raw_fGetIntegerv(GLenum pname, GLint *params) {
1075 BEFORE_GL_CALL;
1076 mSymbols.fGetIntegerv(pname, params);
1077 AFTER_GL_CALL;
1078 }
1080 public:
1082 void fGetIntegerv(GLenum pname, GLint *params) {
1083 switch (pname)
1084 {
1085 // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
1086 // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
1087 // so we don't need two cases.
1088 case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
1089 if (mScreen) {
1090 *params = mScreen->GetDrawFB();
1091 } else {
1092 raw_fGetIntegerv(pname, params);
1093 }
1094 break;
1096 case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
1097 if (mScreen) {
1098 *params = mScreen->GetReadFB();
1099 } else {
1100 raw_fGetIntegerv(pname, params);
1101 }
1102 break;
1104 case LOCAL_GL_MAX_TEXTURE_SIZE:
1105 MOZ_ASSERT(mMaxTextureSize>0);
1106 *params = mMaxTextureSize;
1107 break;
1109 case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1110 MOZ_ASSERT(mMaxCubeMapTextureSize>0);
1111 *params = mMaxCubeMapTextureSize;
1112 break;
1114 case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
1115 MOZ_ASSERT(mMaxRenderbufferSize>0);
1116 *params = mMaxRenderbufferSize;
1117 break;
1119 case LOCAL_GL_VIEWPORT:
1120 for (size_t i = 0; i < 4; i++) {
1121 params[i] = mViewportRect[i];
1122 }
1123 break;
1125 case LOCAL_GL_SCISSOR_BOX:
1126 for (size_t i = 0; i < 4; i++) {
1127 params[i] = mScissorRect[i];
1128 }
1129 break;
1131 default:
1132 raw_fGetIntegerv(pname, params);
1133 break;
1134 }
1135 }
1137 void GetUIntegerv(GLenum pname, GLuint *params) {
1138 fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
1139 }
1141 void fGetFloatv(GLenum pname, GLfloat *params) {
1142 BEFORE_GL_CALL;
1143 mSymbols.fGetFloatv(pname, params);
1144 AFTER_GL_CALL;
1145 }
1147 void fGetBooleanv(GLenum pname, realGLboolean *params) {
1148 BEFORE_GL_CALL;
1149 mSymbols.fGetBooleanv(pname, params);
1150 AFTER_GL_CALL;
1151 }
1153 void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
1154 BEFORE_GL_CALL;
1155 mSymbols.fGetBufferParameteriv(target, pname, params);
1156 AFTER_GL_CALL;
1157 }
1159 GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
1160 BEFORE_GL_CALL;
1161 ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
1162 GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
1163 AFTER_GL_CALL;
1164 return ret;
1165 }
1167 void fGetPointerv(GLenum pname, GLvoid** params) {
1168 BEFORE_GL_CALL;
1169 ASSERT_SYMBOL_PRESENT(fGetPointerv);
1170 mSymbols.fGetPointerv(pname, params);
1171 AFTER_GL_CALL;
1172 }
1174 void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
1175 BEFORE_GL_CALL;
1176 ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
1177 mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
1178 AFTER_GL_CALL;
1179 }
1181 void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
1182 BEFORE_GL_CALL;
1183 ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
1184 mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
1185 AFTER_GL_CALL;
1186 }
1188 void fGenerateMipmap(GLenum target) {
1189 BEFORE_GL_CALL;
1190 mSymbols.fGenerateMipmap(target);
1191 AFTER_GL_CALL;
1192 }
1194 void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
1195 BEFORE_GL_CALL;
1196 mSymbols.fGetProgramiv(program, pname, param);
1197 AFTER_GL_CALL;
1198 }
1200 void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1201 BEFORE_GL_CALL;
1202 mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
1203 AFTER_GL_CALL;
1204 }
1206 void fTexParameteri(GLenum target, GLenum pname, GLint param) {
1207 BEFORE_GL_CALL;
1208 mSymbols.fTexParameteri(target, pname, param);
1209 AFTER_GL_CALL;
1210 }
1212 void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
1213 BEFORE_GL_CALL;
1214 mSymbols.fTexParameteriv(target, pname, params);
1215 AFTER_GL_CALL;
1216 }
1218 void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
1219 BEFORE_GL_CALL;
1220 mSymbols.fTexParameterf(target, pname, param);
1221 AFTER_GL_CALL;
1222 }
1224 const GLubyte* fGetString(GLenum name) {
1225 BEFORE_GL_CALL;
1226 const GLubyte *result = mSymbols.fGetString(name);
1227 AFTER_GL_CALL;
1228 return result;
1229 }
1231 void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) {
1232 BEFORE_GL_CALL;
1233 ASSERT_SYMBOL_PRESENT(fGetTexImage);
1234 mSymbols.fGetTexImage(target, level, format, type, img);
1235 AFTER_GL_CALL;
1236 }
1238 void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
1239 {
1240 BEFORE_GL_CALL;
1241 ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
1242 mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
1243 AFTER_GL_CALL;
1244 }
1246 void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
1247 BEFORE_GL_CALL;
1248 mSymbols.fGetTexParameterfv(target, pname, params);
1249 AFTER_GL_CALL;
1250 }
1252 void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
1253 BEFORE_GL_CALL;
1254 mSymbols.fGetTexParameteriv(target, pname, params);
1255 AFTER_GL_CALL;
1256 }
1258 void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
1259 BEFORE_GL_CALL;
1260 mSymbols.fGetUniformfv(program, location, params);
1261 AFTER_GL_CALL;
1262 }
1264 void fGetUniformiv(GLuint program, GLint location, GLint* params) {
1265 BEFORE_GL_CALL;
1266 mSymbols.fGetUniformiv(program, location, params);
1267 AFTER_GL_CALL;
1268 }
1270 GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
1271 BEFORE_GL_CALL;
1272 GLint retval = mSymbols.fGetUniformLocation(programObj, name);
1273 AFTER_GL_CALL;
1274 return retval;
1275 }
1277 void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
1278 BEFORE_GL_CALL;
1279 mSymbols.fGetVertexAttribfv(index, pname, retval);
1280 AFTER_GL_CALL;
1281 }
1283 void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
1284 BEFORE_GL_CALL;
1285 mSymbols.fGetVertexAttribiv(index, pname, retval);
1286 AFTER_GL_CALL;
1287 }
1289 void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
1290 BEFORE_GL_CALL;
1291 mSymbols.fGetVertexAttribPointerv(index, pname, retval);
1292 AFTER_GL_CALL;
1293 }
1295 void fHint(GLenum target, GLenum mode) {
1296 BEFORE_GL_CALL;
1297 mSymbols.fHint(target, mode);
1298 AFTER_GL_CALL;
1299 }
1301 realGLboolean fIsBuffer(GLuint buffer) {
1302 BEFORE_GL_CALL;
1303 realGLboolean retval = mSymbols.fIsBuffer(buffer);
1304 AFTER_GL_CALL;
1305 return retval;
1306 }
1308 realGLboolean fIsEnabled(GLenum capability) {
1309 BEFORE_GL_CALL;
1310 realGLboolean retval = mSymbols.fIsEnabled(capability);
1311 AFTER_GL_CALL;
1312 return retval;
1313 }
1315 realGLboolean fIsProgram(GLuint program) {
1316 BEFORE_GL_CALL;
1317 realGLboolean retval = mSymbols.fIsProgram(program);
1318 AFTER_GL_CALL;
1319 return retval;
1320 }
1322 realGLboolean fIsShader(GLuint shader) {
1323 BEFORE_GL_CALL;
1324 realGLboolean retval = mSymbols.fIsShader(shader);
1325 AFTER_GL_CALL;
1326 return retval;
1327 }
1329 realGLboolean fIsTexture(GLuint texture) {
1330 BEFORE_GL_CALL;
1331 realGLboolean retval = mSymbols.fIsTexture(texture);
1332 AFTER_GL_CALL;
1333 return retval;
1334 }
1336 void fLineWidth(GLfloat width) {
1337 BEFORE_GL_CALL;
1338 mSymbols.fLineWidth(width);
1339 AFTER_GL_CALL;
1340 }
1342 void fLinkProgram(GLuint program) {
1343 BEFORE_GL_CALL;
1344 mSymbols.fLinkProgram(program);
1345 AFTER_GL_CALL;
1346 }
1348 void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) {
1349 BEFORE_GL_CALL;
1350 ASSERT_SYMBOL_PRESENT(fObjectLabel);
1351 mSymbols.fObjectLabel(identifier, name, length, label);
1352 AFTER_GL_CALL;
1353 }
1355 void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
1356 BEFORE_GL_CALL;
1357 ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
1358 mSymbols.fObjectPtrLabel(ptr, length, label);
1359 AFTER_GL_CALL;
1360 }
1362 void fLoadIdentity() {
1363 BEFORE_GL_CALL;
1364 mSymbols.fLoadIdentity();
1365 AFTER_GL_CALL;
1366 }
1368 void fLoadMatrixf(const GLfloat *matrix) {
1369 BEFORE_GL_CALL;
1370 mSymbols.fLoadMatrixf(matrix);
1371 AFTER_GL_CALL;
1372 }
1374 void fMatrixMode(GLenum mode) {
1375 BEFORE_GL_CALL;
1376 mSymbols.fMatrixMode(mode);
1377 AFTER_GL_CALL;
1378 }
1380 void fPixelStorei(GLenum pname, GLint param) {
1381 BEFORE_GL_CALL;
1382 mSymbols.fPixelStorei(pname, param);
1383 AFTER_GL_CALL;
1384 }
1386 void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid *pointer) {
1387 BEFORE_GL_CALL;
1388 mSymbols.fTextureRangeAPPLE(target, length, pointer);
1389 AFTER_GL_CALL;
1390 }
1392 void fPointParameterf(GLenum pname, GLfloat param) {
1393 BEFORE_GL_CALL;
1394 mSymbols.fPointParameterf(pname, param);
1395 AFTER_GL_CALL;
1396 }
1398 void fPolygonOffset(GLfloat factor, GLfloat bias) {
1399 BEFORE_GL_CALL;
1400 mSymbols.fPolygonOffset(factor, bias);
1401 AFTER_GL_CALL;
1402 }
1404 void fPopDebugGroup() {
1405 BEFORE_GL_CALL;
1406 ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
1407 mSymbols.fPopDebugGroup();
1408 AFTER_GL_CALL;
1409 }
1411 void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
1412 BEFORE_GL_CALL;
1413 ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
1414 mSymbols.fPushDebugGroup(source, id, length, message);
1415 AFTER_GL_CALL;
1416 }
1418 void fReadBuffer(GLenum mode) {
1419 BEFORE_GL_CALL;
1420 mSymbols.fReadBuffer(mode);
1421 AFTER_GL_CALL;
1422 }
1424 private:
1425 void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
1426 BEFORE_GL_CALL;
1427 mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
1428 AFTER_GL_CALL;
1429 }
1431 public:
1432 void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
1433 BeforeGLReadCall();
1435 bool didReadPixels = false;
1436 if (mScreen) {
1437 didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels);
1438 }
1440 if (!didReadPixels) {
1441 raw_fReadPixels(x, y, width, height, format, type, pixels);
1442 }
1444 AfterGLReadCall();
1445 }
1447 public:
1448 void fSampleCoverage(GLclampf value, realGLboolean invert) {
1449 BEFORE_GL_CALL;
1450 mSymbols.fSampleCoverage(value, invert);
1451 AFTER_GL_CALL;
1452 }
1454 void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1455 if (mScissorRect[0] == x &&
1456 mScissorRect[1] == y &&
1457 mScissorRect[2] == width &&
1458 mScissorRect[3] == height)
1459 {
1460 return;
1461 }
1462 mScissorRect[0] = x;
1463 mScissorRect[1] = y;
1464 mScissorRect[2] = width;
1465 mScissorRect[3] = height;
1466 BEFORE_GL_CALL;
1467 mSymbols.fScissor(x, y, width, height);
1468 AFTER_GL_CALL;
1469 }
1471 void fStencilFunc(GLenum func, GLint ref, GLuint mask) {
1472 BEFORE_GL_CALL;
1473 mSymbols.fStencilFunc(func, ref, mask);
1474 AFTER_GL_CALL;
1475 }
1477 void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {
1478 BEFORE_GL_CALL;
1479 mSymbols.fStencilFuncSeparate(frontfunc, backfunc, ref, mask);
1480 AFTER_GL_CALL;
1481 }
1483 void fStencilMask(GLuint mask) {
1484 BEFORE_GL_CALL;
1485 mSymbols.fStencilMask(mask);
1486 AFTER_GL_CALL;
1487 }
1489 void fStencilMaskSeparate(GLenum face, GLuint mask) {
1490 BEFORE_GL_CALL;
1491 mSymbols.fStencilMaskSeparate(face, mask);
1492 AFTER_GL_CALL;
1493 }
1495 void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
1496 BEFORE_GL_CALL;
1497 mSymbols.fStencilOp(fail, zfail, zpass);
1498 AFTER_GL_CALL;
1499 }
1501 void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
1502 BEFORE_GL_CALL;
1503 mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
1504 AFTER_GL_CALL;
1505 }
1507 void fTexGeni(GLenum coord, GLenum pname, GLint param) {
1508 BEFORE_GL_CALL;
1509 mSymbols.fTexGeni(coord, pname, param);
1510 AFTER_GL_CALL;
1511 }
1513 void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
1514 BEFORE_GL_CALL;
1515 mSymbols.fTexGenf(coord, pname, param);
1516 AFTER_GL_CALL;
1517 }
1519 void fTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) {
1520 BEFORE_GL_CALL;
1521 mSymbols.fTexGenfv(coord, pname, params);
1522 AFTER_GL_CALL;
1523 }
1525 private:
1526 void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
1527 BEFORE_GL_CALL;
1528 mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1529 AFTER_GL_CALL;
1530 }
1532 public:
1533 void fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
1534 if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
1535 // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
1536 // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
1537 level = -1;
1538 width = -1;
1539 height = -1;
1540 border = -1;
1541 }
1542 raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1543 }
1545 void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
1546 BEFORE_GL_CALL;
1547 mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
1548 AFTER_GL_CALL;
1549 }
1551 void fUniform1f(GLint location, GLfloat v0) {
1552 BEFORE_GL_CALL;
1553 mSymbols.fUniform1f(location, v0);
1554 AFTER_GL_CALL;
1555 }
1557 void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
1558 BEFORE_GL_CALL;
1559 mSymbols.fUniform1fv(location, count, value);
1560 AFTER_GL_CALL;
1561 }
1563 void fUniform1i(GLint location, GLint v0) {
1564 BEFORE_GL_CALL;
1565 mSymbols.fUniform1i(location, v0);
1566 AFTER_GL_CALL;
1567 }
1569 void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
1570 BEFORE_GL_CALL;
1571 mSymbols.fUniform1iv(location, count, value);
1572 AFTER_GL_CALL;
1573 }
1575 void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
1576 BEFORE_GL_CALL;
1577 mSymbols.fUniform2f(location, v0, v1);
1578 AFTER_GL_CALL;
1579 }
1581 void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
1582 BEFORE_GL_CALL;
1583 mSymbols.fUniform2fv(location, count, value);
1584 AFTER_GL_CALL;
1585 }
1587 void fUniform2i(GLint location, GLint v0, GLint v1) {
1588 BEFORE_GL_CALL;
1589 mSymbols.fUniform2i(location, v0, v1);
1590 AFTER_GL_CALL;
1591 }
1593 void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
1594 BEFORE_GL_CALL;
1595 mSymbols.fUniform2iv(location, count, value);
1596 AFTER_GL_CALL;
1597 }
1599 void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
1600 BEFORE_GL_CALL;
1601 mSymbols.fUniform3f(location, v0, v1, v2);
1602 AFTER_GL_CALL;
1603 }
1605 void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
1606 BEFORE_GL_CALL;
1607 mSymbols.fUniform3fv(location, count, value);
1608 AFTER_GL_CALL;
1609 }
1611 void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
1612 BEFORE_GL_CALL;
1613 mSymbols.fUniform3i(location, v0, v1, v2);
1614 AFTER_GL_CALL;
1615 }
1617 void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
1618 BEFORE_GL_CALL;
1619 mSymbols.fUniform3iv(location, count, value);
1620 AFTER_GL_CALL;
1621 }
1623 void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
1624 BEFORE_GL_CALL;
1625 mSymbols.fUniform4f(location, v0, v1, v2, v3);
1626 AFTER_GL_CALL;
1627 }
1629 void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
1630 BEFORE_GL_CALL;
1631 mSymbols.fUniform4fv(location, count, value);
1632 AFTER_GL_CALL;
1633 }
1635 void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
1636 BEFORE_GL_CALL;
1637 mSymbols.fUniform4i(location, v0, v1, v2, v3);
1638 AFTER_GL_CALL;
1639 }
1641 void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
1642 BEFORE_GL_CALL;
1643 mSymbols.fUniform4iv(location, count, value);
1644 AFTER_GL_CALL;
1645 }
1647 void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1648 BEFORE_GL_CALL;
1649 mSymbols.fUniformMatrix2fv(location, count, transpose, value);
1650 AFTER_GL_CALL;
1651 }
1653 void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1654 BEFORE_GL_CALL;
1655 mSymbols.fUniformMatrix3fv(location, count, transpose, value);
1656 AFTER_GL_CALL;
1657 }
1659 void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1660 BEFORE_GL_CALL;
1661 mSymbols.fUniformMatrix4fv(location, count, transpose, value);
1662 AFTER_GL_CALL;
1663 }
1665 void fUseProgram(GLuint program) {
1666 BEFORE_GL_CALL;
1667 mSymbols.fUseProgram(program);
1668 AFTER_GL_CALL;
1669 }
1671 void fValidateProgram(GLuint program) {
1672 BEFORE_GL_CALL;
1673 mSymbols.fValidateProgram(program);
1674 AFTER_GL_CALL;
1675 }
1677 void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
1678 BEFORE_GL_CALL;
1679 mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
1680 AFTER_GL_CALL;
1681 }
1683 void fVertexAttrib1f(GLuint index, GLfloat x) {
1684 BEFORE_GL_CALL;
1685 mSymbols.fVertexAttrib1f(index, x);
1686 AFTER_GL_CALL;
1687 }
1689 void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1690 BEFORE_GL_CALL;
1691 mSymbols.fVertexAttrib2f(index, x, y);
1692 AFTER_GL_CALL;
1693 }
1695 void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1696 BEFORE_GL_CALL;
1697 mSymbols.fVertexAttrib3f(index, x, y, z);
1698 AFTER_GL_CALL;
1699 }
1701 void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
1702 BEFORE_GL_CALL;
1703 mSymbols.fVertexAttrib4f(index, x, y, z, w);
1704 AFTER_GL_CALL;
1705 }
1707 void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
1708 BEFORE_GL_CALL;
1709 mSymbols.fVertexAttrib1fv(index, v);
1710 AFTER_GL_CALL;
1711 }
1713 void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
1714 BEFORE_GL_CALL;
1715 mSymbols.fVertexAttrib2fv(index, v);
1716 AFTER_GL_CALL;
1717 }
1719 void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
1720 BEFORE_GL_CALL;
1721 mSymbols.fVertexAttrib3fv(index, v);
1722 AFTER_GL_CALL;
1723 }
1725 void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
1726 BEFORE_GL_CALL;
1727 mSymbols.fVertexAttrib4fv(index, v);
1728 AFTER_GL_CALL;
1729 }
1731 void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
1732 BEFORE_GL_CALL;
1733 mSymbols.fVertexPointer(size, type, stride, pointer);
1734 AFTER_GL_CALL;
1735 }
1737 void fCompileShader(GLuint shader) {
1738 BEFORE_GL_CALL;
1739 mSymbols.fCompileShader(shader);
1740 AFTER_GL_CALL;
1741 }
1743 private:
1744 void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
1745 BEFORE_GL_CALL;
1746 mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
1747 AFTER_GL_CALL;
1748 }
1750 void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
1751 BEFORE_GL_CALL;
1752 mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
1753 AFTER_GL_CALL;
1754 }
1756 public:
1757 void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
1758 BEFORE_GL_CALL;
1759 mSymbols.fGetShaderiv(shader, pname, param);
1760 AFTER_GL_CALL;
1761 }
1763 void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1764 BEFORE_GL_CALL;
1765 mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
1766 AFTER_GL_CALL;
1767 }
1769 private:
1770 void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1771 MOZ_ASSERT(IsGLES());
1773 BEFORE_GL_CALL;
1774 ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
1775 mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1776 AFTER_GL_CALL;
1777 }
1779 public:
1780 void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1781 if (IsGLES()) {
1782 raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1783 } else {
1784 // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
1785 GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
1786 }
1787 }
1789 void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
1790 BEFORE_GL_CALL;
1791 mSymbols.fGetShaderSource(obj, maxLength, length, source);
1792 AFTER_GL_CALL;
1793 }
1795 void fShaderSource(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) {
1796 BEFORE_GL_CALL;
1797 mSymbols.fShaderSource(shader, count, strings, lengths);
1798 AFTER_GL_CALL;
1799 }
1801 private:
1802 void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
1803 BEFORE_GL_CALL;
1804 mSymbols.fBindFramebuffer(target, framebuffer);
1805 AFTER_GL_CALL;
1806 }
1808 public:
1809 void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
1810 BEFORE_GL_CALL;
1811 mSymbols.fBindRenderbuffer(target, renderbuffer);
1812 AFTER_GL_CALL;
1813 }
1815 GLenum fCheckFramebufferStatus(GLenum target) {
1816 BEFORE_GL_CALL;
1817 GLenum retval = mSymbols.fCheckFramebufferStatus(target);
1818 AFTER_GL_CALL;
1819 return retval;
1820 }
1822 void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
1823 BEFORE_GL_CALL;
1824 mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
1825 AFTER_GL_CALL;
1826 }
1828 void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
1829 BEFORE_GL_CALL;
1830 mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
1831 AFTER_GL_CALL;
1832 }
1834 void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
1835 BEFORE_GL_CALL;
1836 mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
1837 AFTER_GL_CALL;
1838 }
1840 void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
1841 BEFORE_GL_CALL;
1842 mSymbols.fGetRenderbufferParameteriv(target, pname, value);
1843 AFTER_GL_CALL;
1844 }
1846 realGLboolean fIsFramebuffer (GLuint framebuffer) {
1847 BEFORE_GL_CALL;
1848 realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
1849 AFTER_GL_CALL;
1850 return retval;
1851 }
1853 public:
1854 realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
1855 BEFORE_GL_CALL;
1856 realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
1857 AFTER_GL_CALL;
1858 return retval;
1859 }
1861 void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
1862 BEFORE_GL_CALL;
1863 mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
1864 AFTER_GL_CALL;
1865 }
1867 private:
1868 void raw_fDepthRange(GLclampf a, GLclampf b) {
1869 MOZ_ASSERT(!IsGLES());
1871 BEFORE_GL_CALL;
1872 ASSERT_SYMBOL_PRESENT(fDepthRange);
1873 mSymbols.fDepthRange(a, b);
1874 AFTER_GL_CALL;
1875 }
1877 void raw_fDepthRangef(GLclampf a, GLclampf b) {
1878 MOZ_ASSERT(IsGLES());
1880 BEFORE_GL_CALL;
1881 ASSERT_SYMBOL_PRESENT(fDepthRangef);
1882 mSymbols.fDepthRangef(a, b);
1883 AFTER_GL_CALL;
1884 }
1886 void raw_fClearDepth(GLclampf v) {
1887 MOZ_ASSERT(!IsGLES());
1889 BEFORE_GL_CALL;
1890 ASSERT_SYMBOL_PRESENT(fClearDepth);
1891 mSymbols.fClearDepth(v);
1892 AFTER_GL_CALL;
1893 }
1895 void raw_fClearDepthf(GLclampf v) {
1896 MOZ_ASSERT(IsGLES());
1898 BEFORE_GL_CALL;
1899 ASSERT_SYMBOL_PRESENT(fClearDepthf);
1900 mSymbols.fClearDepthf(v);
1901 AFTER_GL_CALL;
1902 }
1904 public:
1905 void fDepthRange(GLclampf a, GLclampf b) {
1906 if (IsGLES()) {
1907 raw_fDepthRangef(a, b);
1908 } else {
1909 raw_fDepthRange(a, b);
1910 }
1911 }
1913 void fClearDepth(GLclampf v) {
1914 if (IsGLES()) {
1915 raw_fClearDepthf(v);
1916 } else {
1917 raw_fClearDepth(v);
1918 }
1919 }
1921 void* fMapBuffer(GLenum target, GLenum access) {
1922 BEFORE_GL_CALL;
1923 ASSERT_SYMBOL_PRESENT(fMapBuffer);
1924 void *ret = mSymbols.fMapBuffer(target, access);
1925 AFTER_GL_CALL;
1926 return ret;
1927 }
1929 realGLboolean fUnmapBuffer(GLenum target) {
1930 BEFORE_GL_CALL;
1931 ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
1932 realGLboolean ret = mSymbols.fUnmapBuffer(target);
1933 AFTER_GL_CALL;
1934 return ret;
1935 }
1938 private:
1939 GLuint raw_fCreateProgram() {
1940 BEFORE_GL_CALL;
1941 GLuint ret = mSymbols.fCreateProgram();
1942 AFTER_GL_CALL;
1943 return ret;
1944 }
1946 GLuint raw_fCreateShader(GLenum t) {
1947 BEFORE_GL_CALL;
1948 GLuint ret = mSymbols.fCreateShader(t);
1949 AFTER_GL_CALL;
1950 return ret;
1951 }
1953 void raw_fGenBuffers(GLsizei n, GLuint* names) {
1954 BEFORE_GL_CALL;
1955 mSymbols.fGenBuffers(n, names);
1956 AFTER_GL_CALL;
1957 }
1959 void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
1960 BEFORE_GL_CALL;
1961 mSymbols.fGenFramebuffers(n, names);
1962 AFTER_GL_CALL;
1963 }
1965 void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
1966 BEFORE_GL_CALL;
1967 mSymbols.fGenRenderbuffers(n, names);
1968 AFTER_GL_CALL;
1969 }
1971 void raw_fGenTextures(GLsizei n, GLuint* names) {
1972 BEFORE_GL_CALL;
1973 mSymbols.fGenTextures(n, names);
1974 AFTER_GL_CALL;
1975 }
1977 public:
1978 GLuint fCreateProgram() {
1979 GLuint ret = raw_fCreateProgram();
1980 TRACKING_CONTEXT(CreatedProgram(this, ret));
1981 return ret;
1982 }
1984 GLuint fCreateShader(GLenum t) {
1985 GLuint ret = raw_fCreateShader(t);
1986 TRACKING_CONTEXT(CreatedShader(this, ret));
1987 return ret;
1988 }
1990 void fGenBuffers(GLsizei n, GLuint* names) {
1991 raw_fGenBuffers(n, names);
1992 TRACKING_CONTEXT(CreatedBuffers(this, n, names));
1993 }
1995 void fGenFramebuffers(GLsizei n, GLuint* names) {
1996 raw_fGenFramebuffers(n, names);
1997 TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
1998 }
2000 void fGenRenderbuffers(GLsizei n, GLuint* names) {
2001 raw_fGenRenderbuffers(n, names);
2002 TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
2003 }
2005 void fGenTextures(GLsizei n, GLuint* names) {
2006 raw_fGenTextures(n, names);
2007 TRACKING_CONTEXT(CreatedTextures(this, n, names));
2008 }
2010 private:
2011 void raw_fDeleteProgram(GLuint program) {
2012 BEFORE_GL_CALL;
2013 mSymbols.fDeleteProgram(program);
2014 AFTER_GL_CALL;
2015 }
2017 void raw_fDeleteShader(GLuint shader) {
2018 BEFORE_GL_CALL;
2019 mSymbols.fDeleteShader(shader);
2020 AFTER_GL_CALL;
2021 }
2023 void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
2024 BEFORE_GL_CALL;
2025 mSymbols.fDeleteBuffers(n, names);
2026 AFTER_GL_CALL;
2027 }
2029 void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2030 BEFORE_GL_CALL;
2031 mSymbols.fDeleteFramebuffers(n, names);
2032 AFTER_GL_CALL;
2033 }
2035 void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2036 BEFORE_GL_CALL;
2037 mSymbols.fDeleteRenderbuffers(n, names);
2038 AFTER_GL_CALL;
2039 }
2041 void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
2042 BEFORE_GL_CALL;
2043 mSymbols.fDeleteTextures(n, names);
2044 AFTER_GL_CALL;
2045 }
2047 public:
2049 void fDeleteProgram(GLuint program) {
2050 raw_fDeleteProgram(program);
2051 TRACKING_CONTEXT(DeletedProgram(this, program));
2052 }
2054 void fDeleteShader(GLuint shader) {
2055 raw_fDeleteShader(shader);
2056 TRACKING_CONTEXT(DeletedShader(this, shader));
2057 }
2059 void fDeleteBuffers(GLsizei n, const GLuint* names) {
2060 raw_fDeleteBuffers(n, names);
2061 TRACKING_CONTEXT(DeletedBuffers(this, n, names));
2062 }
2064 void fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2065 if (mScreen) {
2066 // Notify mScreen which framebuffers we're deleting.
2067 // Otherwise, we will get framebuffer binding mispredictions.
2068 for (int i = 0; i < n; i++) {
2069 mScreen->DeletingFB(names[i]);
2070 }
2071 }
2073 if (n == 1 && *names == 0) {
2074 // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
2075 } else {
2076 raw_fDeleteFramebuffers(n, names);
2077 }
2078 TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
2079 }
2081 void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2082 raw_fDeleteRenderbuffers(n, names);
2083 TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
2084 }
2086 void fDeleteTextures(GLsizei n, const GLuint* names) {
2087 raw_fDeleteTextures(n, names);
2088 TRACKING_CONTEXT(DeletedTextures(this, n, names));
2089 }
2091 GLenum fGetGraphicsResetStatus() {
2092 MOZ_ASSERT(mHasRobustness);
2094 BEFORE_GL_CALL;
2095 ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
2096 GLenum ret = mSymbols.fGetGraphicsResetStatus();
2097 AFTER_GL_CALL;
2098 return ret;
2099 }
2102 // -----------------------------------------------------------------------------
2103 // Extension ARB_sync (GL)
2104 public:
2105 GLsync fFenceSync(GLenum condition, GLbitfield flags) {
2106 BEFORE_GL_CALL;
2107 ASSERT_SYMBOL_PRESENT(fFenceSync);
2108 GLsync ret = mSymbols.fFenceSync(condition, flags);
2109 AFTER_GL_CALL;
2110 return ret;
2111 }
2113 realGLboolean fIsSync(GLsync sync) {
2114 BEFORE_GL_CALL;
2115 ASSERT_SYMBOL_PRESENT(fIsSync);
2116 realGLboolean ret = mSymbols.fIsSync(sync);
2117 AFTER_GL_CALL;
2118 return ret;
2119 }
2121 void fDeleteSync(GLsync sync) {
2122 BEFORE_GL_CALL;
2123 ASSERT_SYMBOL_PRESENT(fDeleteSync);
2124 mSymbols.fDeleteSync(sync);
2125 AFTER_GL_CALL;
2126 }
2128 GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2129 BEFORE_GL_CALL;
2130 ASSERT_SYMBOL_PRESENT(fClientWaitSync);
2131 GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
2132 AFTER_GL_CALL;
2133 return ret;
2134 }
2136 void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2137 BEFORE_GL_CALL;
2138 ASSERT_SYMBOL_PRESENT(fWaitSync);
2139 mSymbols.fWaitSync(sync, flags, timeout);
2140 AFTER_GL_CALL;
2141 }
2143 void fGetInteger64v(GLenum pname, GLint64 *params) {
2144 BEFORE_GL_CALL;
2145 ASSERT_SYMBOL_PRESENT(fGetInteger64v);
2146 mSymbols.fGetInteger64v(pname, params);
2147 AFTER_GL_CALL;
2148 }
2150 void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
2151 BEFORE_GL_CALL;
2152 ASSERT_SYMBOL_PRESENT(fGetSynciv);
2153 mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
2154 AFTER_GL_CALL;
2155 }
2158 // -----------------------------------------------------------------------------
2159 // Extension OES_EGL_image (GLES)
2160 public:
2161 void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
2162 BEFORE_GL_CALL;
2163 ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
2164 mSymbols.fEGLImageTargetTexture2D(target, image);
2165 AFTER_GL_CALL;
2166 }
2168 void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
2169 {
2170 BEFORE_GL_CALL;
2171 ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
2172 mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
2173 AFTER_GL_CALL;
2174 }
2177 // -----------------------------------------------------------------------------
2178 // Package XXX_bind_buffer_offset
2179 public:
2180 void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
2181 {
2182 BEFORE_GL_CALL;
2183 ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
2184 mSymbols.fBindBufferOffset(target, index, buffer, offset);
2185 AFTER_GL_CALL;
2186 }
2189 // -----------------------------------------------------------------------------
2190 // Package XXX_draw_buffers
2191 public:
2192 void fDrawBuffers(GLsizei n, const GLenum* bufs) {
2193 BEFORE_GL_CALL;
2194 mSymbols.fDrawBuffers(n, bufs);
2195 AFTER_GL_CALL;
2196 }
2199 // -----------------------------------------------------------------------------
2200 // Package XXX_draw_instanced
2201 public:
2202 void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2203 {
2204 BeforeGLDrawCall();
2205 raw_fDrawArraysInstanced(mode, first, count, primcount);
2206 AfterGLDrawCall();
2207 }
2209 void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2210 {
2211 BeforeGLDrawCall();
2212 raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
2213 AfterGLDrawCall();
2214 }
2216 private:
2217 void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2218 {
2219 BEFORE_GL_CALL;
2220 ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
2221 mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
2222 AFTER_GL_CALL;
2223 }
2225 void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2226 {
2227 BEFORE_GL_CALL;
2228 ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
2229 mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
2230 AFTER_GL_CALL;
2231 }
2233 // -----------------------------------------------------------------------------
2234 // Feature draw_range_elements
2235 public:
2236 void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2237 GLsizei count, GLenum type, const GLvoid* indices)
2238 {
2239 BeforeGLDrawCall();
2240 raw_fDrawRangeElements(mode, start, end, count, type, indices);
2241 AfterGLDrawCall();
2242 }
2244 private:
2245 void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2246 GLsizei count, GLenum type, const GLvoid* indices)
2247 {
2248 BEFORE_GL_CALL;
2249 ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
2250 mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
2251 AFTER_GL_CALL;
2252 }
2254 // -----------------------------------------------------------------------------
2255 // Package XXX_framebuffer_blit
2256 public:
2257 // Draw/Read
2258 void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2259 BeforeGLDrawCall();
2260 BeforeGLReadCall();
2261 raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2262 AfterGLReadCall();
2263 AfterGLDrawCall();
2264 }
2267 private:
2268 void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2269 BEFORE_GL_CALL;
2270 ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
2271 mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2272 AFTER_GL_CALL;
2273 }
2276 // -----------------------------------------------------------------------------
2277 // Package XXX_framebuffer_multisample
2278 public:
2279 void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
2280 BEFORE_GL_CALL;
2281 ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
2282 mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
2283 AFTER_GL_CALL;
2284 }
2287 // -----------------------------------------------------------------------------
2288 // Package XXX_instanced_arrays
2289 public:
2290 void fVertexAttribDivisor(GLuint index, GLuint divisor)
2291 {
2292 BEFORE_GL_CALL;
2293 ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
2294 mSymbols.fVertexAttribDivisor(index, divisor);
2295 AFTER_GL_CALL;
2296 }
2299 // -----------------------------------------------------------------------------
2300 // Package XXX_query_objects
2301 /**
2302 * XXX_query_objects:
2303 * - provide all followed entry points
2304 *
2305 * XXX_occlusion_query2:
2306 * - depends on XXX_query_objects
2307 * - provide ANY_SAMPLES_PASSED
2308 *
2309 * XXX_occlusion_query_boolean:
2310 * - depends on XXX_occlusion_query2
2311 * - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2312 */
2313 public:
2314 void fDeleteQueries(GLsizei n, const GLuint* names) {
2315 BEFORE_GL_CALL;
2316 ASSERT_SYMBOL_PRESENT(fDeleteQueries);
2317 mSymbols.fDeleteQueries(n, names);
2318 AFTER_GL_CALL;
2319 TRACKING_CONTEXT(DeletedQueries(this, n, names));
2320 }
2322 void fGenQueries(GLsizei n, GLuint* names) {
2323 BEFORE_GL_CALL;
2324 ASSERT_SYMBOL_PRESENT(fGenQueries);
2325 mSymbols.fGenQueries(n, names);
2326 AFTER_GL_CALL;
2327 TRACKING_CONTEXT(CreatedQueries(this, n, names));
2328 }
2330 void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
2331 BEFORE_GL_CALL;
2332 ASSERT_SYMBOL_PRESENT(fGetQueryiv);
2333 mSymbols.fGetQueryiv(target, pname, params);
2334 AFTER_GL_CALL;
2335 }
2337 void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
2338 BEFORE_GL_CALL;
2339 ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
2340 mSymbols.fGetQueryObjectuiv(id, pname, params);
2341 AFTER_GL_CALL;
2342 }
2344 realGLboolean fIsQuery(GLuint query) {
2345 BEFORE_GL_CALL;
2346 ASSERT_SYMBOL_PRESENT(fIsQuery);
2347 realGLboolean retval = mSymbols.fIsQuery(query);
2348 AFTER_GL_CALL;
2349 return retval;
2350 }
2353 // -----------------------------------------------------------------------------
2354 // Package XXX_get_query_object_iv
2355 /**
2356 * XXX_get_query_object_iv:
2357 * - depends on XXX_query_objects
2358 * - provide the followed entry point
2359 *
2360 * XXX_occlusion_query:
2361 * - depends on XXX_get_query_object_iv
2362 * - provide LOCAL_GL_SAMPLES_PASSED
2363 */
2364 public:
2365 void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
2366 BEFORE_GL_CALL;
2367 ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
2368 mSymbols.fGetQueryObjectiv(id, pname, params);
2369 AFTER_GL_CALL;
2370 }
2373 // -----------------------------------------------------------------------------
2374 // Package XXX_transform_feedback
2375 public:
2376 void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
2377 {
2378 BEFORE_GL_CALL;
2379 ASSERT_SYMBOL_PRESENT(fBindBufferBase);
2380 mSymbols.fBindBufferBase(target, index, buffer);
2381 AFTER_GL_CALL;
2382 }
2384 void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
2385 {
2386 BEFORE_GL_CALL;
2387 ASSERT_SYMBOL_PRESENT(fBindBufferRange);
2388 mSymbols.fBindBufferRange(target, index, buffer, offset, size);
2389 AFTER_GL_CALL;
2390 }
2392 void fBeginTransformFeedback(GLenum primitiveMode)
2393 {
2394 BEFORE_GL_CALL;
2395 ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
2396 mSymbols.fBeginTransformFeedback(primitiveMode);
2397 AFTER_GL_CALL;
2398 }
2400 void fEndTransformFeedback()
2401 {
2402 BEFORE_GL_CALL;
2403 ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
2404 mSymbols.fEndTransformFeedback();
2405 AFTER_GL_CALL;
2406 }
2408 void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
2409 {
2410 BEFORE_GL_CALL;
2411 ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
2412 mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
2413 AFTER_GL_CALL;
2414 }
2416 void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
2417 {
2418 BEFORE_GL_CALL;
2419 ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
2420 mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
2421 AFTER_GL_CALL;
2422 }
2424 void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
2425 {
2426 BEFORE_GL_CALL;
2427 ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
2428 mSymbols.fGetIntegeri_v(param, index, values);
2429 AFTER_GL_CALL;
2430 }
2433 // -----------------------------------------------------------------------------
2434 // Package XXX_vertex_array_object
2435 public:
2436 void fBindVertexArray(GLuint array)
2437 {
2438 BEFORE_GL_CALL;
2439 ASSERT_SYMBOL_PRESENT(fBindVertexArray);
2440 mSymbols.fBindVertexArray(array);
2441 AFTER_GL_CALL;
2442 }
2444 void fDeleteVertexArrays(GLsizei n, const GLuint *arrays)
2445 {
2446 BEFORE_GL_CALL;
2447 ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
2448 mSymbols.fDeleteVertexArrays(n, arrays);
2449 AFTER_GL_CALL;
2450 }
2452 void fGenVertexArrays(GLsizei n, GLuint *arrays)
2453 {
2454 BEFORE_GL_CALL;
2455 ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
2456 mSymbols.fGenVertexArrays(n, arrays);
2457 AFTER_GL_CALL;
2458 }
2460 realGLboolean fIsVertexArray(GLuint array)
2461 {
2462 BEFORE_GL_CALL;
2463 ASSERT_SYMBOL_PRESENT(fIsVertexArray);
2464 realGLboolean ret = mSymbols.fIsVertexArray(array);
2465 AFTER_GL_CALL;
2466 return ret;
2467 }
2470 // -----------------------------------------------------------------------------
2471 // Constructor
2472 public:
2474 typedef struct gfx::SurfaceCaps SurfaceCaps;
2477 protected:
2478 GLContext(const SurfaceCaps& caps,
2479 GLContext* sharedContext = nullptr,
2480 bool isOffscreen = false);
2483 // -----------------------------------------------------------------------------
2484 // Destructor
2485 public:
2486 virtual ~GLContext();
2489 // -----------------------------------------------------------------------------
2490 // Everything that isn't standard GL APIs
2491 protected:
2492 typedef class gfx::SharedSurface SharedSurface;
2493 typedef gfx::SharedSurfaceType SharedSurfaceType;
2494 typedef gfx::SurfaceFormat SurfaceFormat;
2496 virtual bool MakeCurrentImpl(bool aForce) = 0;
2498 public:
2499 #ifdef MOZ_ENABLE_GL_TRACKING
2500 static void StaticInit() {
2501 PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
2502 }
2503 #endif
2505 bool MakeCurrent(bool aForce = false) {
2506 if (IsDestroyed()) {
2507 return false;
2508 }
2509 #ifdef MOZ_ENABLE_GL_TRACKING
2510 PR_SetThreadPrivate(sCurrentGLContextTLS, this);
2512 // XXX this assertion is disabled because it's triggering on Mac;
2513 // we need to figure out why and reenable it.
2514 #if 0
2515 // IsOwningThreadCurrent is a bit of a misnomer;
2516 // the "owning thread" is the creation thread,
2517 // and the only thread that can own this. We don't
2518 // support contexts used on multiple threads.
2519 NS_ASSERTION(IsOwningThreadCurrent(),
2520 "MakeCurrent() called on different thread than this context was created on!");
2521 #endif
2522 #endif
2523 return MakeCurrentImpl(aForce);
2524 }
2526 virtual bool Init() = 0;
2528 virtual bool SetupLookupFunction() = 0;
2530 virtual void ReleaseSurface() {}
2532 // Mark this context as destroyed. This will nullptr out all
2533 // the GL function pointers!
2534 void MarkDestroyed();
2536 bool IsDestroyed() {
2537 // MarkDestroyed will mark all these as null.
2538 return mSymbols.fUseProgram == nullptr;
2539 }
2541 GLContext *GetSharedContext() { return mSharedContext; }
2543 /**
2544 * Returns true if the thread on which this context was created is the currently
2545 * executing thread.
2546 */
2547 bool IsOwningThreadCurrent();
2548 void DispatchToOwningThread(nsIRunnable *event);
2550 static void PlatformStartup();
2552 public:
2553 /**
2554 * If this context wraps a double-buffered target, swap the back
2555 * and front buffers. It should be assumed that after a swap, the
2556 * contents of the new back buffer are undefined.
2557 */
2558 virtual bool SwapBuffers() { return false; }
2560 /**
2561 * Defines a two-dimensional texture image for context target surface
2562 */
2563 virtual bool BindTexImage() { return false; }
2564 /*
2565 * Releases a color buffer that is being used as a texture
2566 */
2567 virtual bool ReleaseTexImage() { return false; }
2569 // Before reads from offscreen texture
2570 void GuaranteeResolve();
2572 /*
2573 * Resize the current offscreen buffer. Returns true on success.
2574 * If it returns false, the context should be treated as unusable
2575 * and should be recreated. After the resize, the viewport is not
2576 * changed; glViewport should be called as appropriate.
2577 *
2578 * Only valid if IsOffscreen() returns true.
2579 */
2580 bool ResizeOffscreen(const gfx::IntSize& size) {
2581 return ResizeScreenBuffer(size);
2582 }
2584 /*
2585 * Return size of this offscreen context.
2586 *
2587 * Only valid if IsOffscreen() returns true.
2588 */
2589 const gfx::IntSize& OffscreenSize() const;
2591 void BindFB(GLuint fb) {
2592 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
2593 MOZ_ASSERT(!fb || fIsFramebuffer(fb));
2594 }
2596 void BindDrawFB(GLuint fb) {
2597 fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
2598 }
2600 void BindReadFB(GLuint fb) {
2601 fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
2602 }
2604 GLuint GetDrawFB() {
2605 if (mScreen)
2606 return mScreen->GetDrawFB();
2608 GLuint ret = 0;
2609 GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
2610 return ret;
2611 }
2613 GLuint GetReadFB() {
2614 if (mScreen)
2615 return mScreen->GetReadFB();
2617 GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit)
2618 ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
2619 : LOCAL_GL_FRAMEBUFFER_BINDING;
2621 GLuint ret = 0;
2622 GetUIntegerv(bindEnum, &ret);
2623 return ret;
2624 }
2626 GLuint GetFB() {
2627 if (mScreen) {
2628 // This has a very important extra assert that checks that we're
2629 // not accidentally ignoring a situation where the draw and read
2630 // FBs differ.
2631 return mScreen->GetFB();
2632 }
2634 GLuint ret = 0;
2635 GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
2636 return ret;
2637 }
2639 private:
2640 void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
2641 switch (precisiontype) {
2642 case LOCAL_GL_LOW_FLOAT:
2643 case LOCAL_GL_MEDIUM_FLOAT:
2644 case LOCAL_GL_HIGH_FLOAT:
2645 // Assume IEEE 754 precision
2646 range[0] = 127;
2647 range[1] = 127;
2648 *precision = 23;
2649 break;
2650 case LOCAL_GL_LOW_INT:
2651 case LOCAL_GL_MEDIUM_INT:
2652 case LOCAL_GL_HIGH_INT:
2653 // Some (most) hardware only supports single-precision floating-point numbers,
2654 // which can accurately represent integers up to +/-16777216
2655 range[0] = 24;
2656 range[1] = 24;
2657 *precision = 0;
2658 break;
2659 }
2660 }
2662 public:
2664 void ForceDirtyScreen();
2665 void CleanDirtyScreen();
2667 virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
2669 virtual bool RenewSurface() { return false; }
2671 // Shared code for GL extensions and GLX extensions.
2672 static bool ListHasExtension(const GLubyte *extensions,
2673 const char *extension);
2675 GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
2677 public:
2678 /**
2679 * Context reset constants.
2680 * These are used to determine who is guilty when a context reset
2681 * happens.
2682 */
2683 enum ContextResetARB {
2684 CONTEXT_NO_ERROR = 0,
2685 CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253,
2686 CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
2687 CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255
2688 };
2690 public:
2691 std::map<GLuint, SharedSurface_GL*> mFBOMapping;
2693 enum {
2694 DebugEnabled = 1 << 0,
2695 DebugTrace = 1 << 1,
2696 DebugAbortOnError = 1 << 2
2697 };
2699 static uint32_t sDebugMode;
2701 static uint32_t DebugMode() {
2702 #ifdef DEBUG
2703 return sDebugMode;
2704 #else
2705 return 0;
2706 #endif
2707 }
2709 protected:
2710 nsRefPtr<GLContext> mSharedContext;
2712 // The thread on which this context was created.
2713 nsCOMPtr<nsIThread> mOwningThread;
2715 GLContextSymbols mSymbols;
2717 #ifdef DEBUG
2718 // GLDebugMode will check that we don't send call
2719 // to a GLContext that isn't current on the current
2720 // thread.
2721 // Store the current context when binding to thread local
2722 // storage to support DebugMode on an arbitrary thread.
2723 static unsigned sCurrentGLContextTLS;
2724 #endif
2726 ScopedDeletePtr<GLBlitHelper> mBlitHelper;
2727 ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
2728 ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
2730 public:
2731 GLBlitHelper* BlitHelper();
2732 GLBlitTextureImageHelper* BlitTextureImageHelper();
2733 GLReadTexImageHelper* ReadTexImageHelper();
2735 // Assumes shares are created by all sharing with the same global context.
2736 bool SharesWith(const GLContext* other) const {
2737 MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
2738 MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
2739 MOZ_ASSERT(!this->mSharedContext ||
2740 !other->mSharedContext ||
2741 this->mSharedContext == other->mSharedContext);
2743 const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
2744 : this;
2745 const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
2746 : other;
2748 return thisShared == otherShared;
2749 }
2751 bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps) {
2752 if (!CreateScreenBuffer(size, caps))
2753 return false;
2755 MakeCurrent();
2756 fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
2757 fScissor(0, 0, size.width, size.height);
2758 fViewport(0, 0, size.width, size.height);
2760 mCaps = mScreen->Caps();
2761 if (mCaps.any)
2762 DetermineCaps();
2764 UpdateGLFormats(mCaps);
2765 UpdatePixelFormat();
2767 return true;
2768 }
2770 protected:
2771 // Note that it does -not- clear the resized buffers.
2772 bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
2773 if (!IsOffscreenSizeAllowed(size))
2774 return false;
2776 SurfaceCaps tryCaps = caps;
2777 if (tryCaps.antialias) {
2778 // AA path
2779 if (CreateScreenBufferImpl(size, tryCaps))
2780 return true;
2782 NS_WARNING("CreateScreenBuffer failed to initialize an AA context! Falling back to no AA...");
2783 tryCaps.antialias = false;
2784 }
2785 MOZ_ASSERT(!tryCaps.antialias);
2787 if (CreateScreenBufferImpl(size, tryCaps))
2788 return true;
2790 NS_WARNING("CreateScreenBuffer failed to initialize non-AA context!");
2791 return false;
2792 }
2794 bool CreateScreenBufferImpl(const gfx::IntSize& size,
2795 const SurfaceCaps& caps);
2797 public:
2798 bool ResizeScreenBuffer(const gfx::IntSize& size);
2800 protected:
2801 SurfaceCaps mCaps;
2802 nsAutoPtr<GLFormats> mGLFormats;
2803 nsAutoPtr<PixelBufferFormat> mPixelFormat;
2805 public:
2806 void DetermineCaps();
2807 const SurfaceCaps& Caps() const {
2808 return mCaps;
2809 }
2811 // Only varies based on bpp16 and alpha.
2812 GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
2813 void UpdateGLFormats(const SurfaceCaps& caps) {
2814 mGLFormats = new GLFormats(ChooseGLFormats(caps));
2815 }
2817 const GLFormats& GetGLFormats() const {
2818 MOZ_ASSERT(mGLFormats);
2819 return *mGLFormats;
2820 }
2822 PixelBufferFormat QueryPixelFormat();
2823 void UpdatePixelFormat();
2825 const PixelBufferFormat& GetPixelFormat() const {
2826 MOZ_ASSERT(mPixelFormat);
2827 return *mPixelFormat;
2828 }
2830 bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
2832 // Does not check completeness.
2833 void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
2834 GLuint depthRB, GLuint stencilRB,
2835 GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
2837 // Passing null is fine if the value you'd get is 0.
2838 bool AssembleOffscreenFBs(const GLuint colorMSRB,
2839 const GLuint depthRB,
2840 const GLuint stencilRB,
2841 const GLuint texture,
2842 GLuint* drawFB,
2843 GLuint* readFB);
2845 protected:
2846 friend class GLScreenBuffer;
2847 GLScreenBuffer* mScreen;
2849 void DestroyScreenBuffer();
2851 SharedSurface_GL* mLockedSurface;
2853 public:
2854 void LockSurface(SharedSurface_GL* surf) {
2855 MOZ_ASSERT(!mLockedSurface);
2856 mLockedSurface = surf;
2857 }
2859 void UnlockSurface(SharedSurface_GL* surf) {
2860 MOZ_ASSERT(mLockedSurface == surf);
2861 mLockedSurface = nullptr;
2862 }
2864 SharedSurface_GL* GetLockedSurface() const {
2865 return mLockedSurface;
2866 }
2868 bool IsOffscreen() const {
2869 return mScreen;
2870 }
2872 GLScreenBuffer* Screen() const {
2873 return mScreen;
2874 }
2876 bool PublishFrame();
2877 SharedSurface_GL* RequestFrame();
2879 /* Clear to transparent black, with 0 depth and stencil,
2880 * while preserving current ClearColor etc. values.
2881 * Useful for resizing offscreen buffers.
2882 */
2883 void ClearSafely();
2885 bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
2887 protected:
2888 nsRefPtr<TextureGarbageBin> mTexGarbageBin;
2890 public:
2891 TextureGarbageBin* TexGarbageBin() {
2892 MOZ_ASSERT(mTexGarbageBin);
2893 return mTexGarbageBin;
2894 }
2896 void EmptyTexGarbageBin();
2898 bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
2900 protected:
2901 bool InitWithPrefix(const char *prefix, bool trygl);
2903 void InitExtensions();
2905 GLint mViewportRect[4];
2906 GLint mScissorRect[4];
2908 GLint mMaxTextureSize;
2909 GLint mMaxCubeMapTextureSize;
2910 GLint mMaxTextureImageSize;
2911 GLint mMaxRenderbufferSize;
2912 GLsizei mMaxSamples;
2913 bool mNeedsTextureSizeChecks;
2914 bool mWorkAroundDriverBugs;
2916 bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
2917 if (mNeedsTextureSizeChecks) {
2918 // some drivers incorrectly handle some large texture sizes that are below the
2919 // max texture size that they report. So we check ourselves against our own values
2920 // (mMax[CubeMap]TextureSize).
2921 // see bug 737182 for Mac Intel 2D textures
2922 // see bug 684882 for Mac Intel cube map textures
2923 // see bug 814716 for Mesa Nouveau
2924 GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
2925 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
2926 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
2927 ? mMaxCubeMapTextureSize
2928 : mMaxTextureSize;
2929 return width <= maxSize && height <= maxSize;
2930 }
2931 return true;
2932 }
2935 public:
2937 void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
2938 if (mViewportRect[0] == x &&
2939 mViewportRect[1] == y &&
2940 mViewportRect[2] == width &&
2941 mViewportRect[3] == height)
2942 {
2943 return;
2944 }
2945 mViewportRect[0] = x;
2946 mViewportRect[1] = y;
2947 mViewportRect[2] = width;
2948 mViewportRect[3] = height;
2949 BEFORE_GL_CALL;
2950 mSymbols.fViewport(x, y, width, height);
2951 AFTER_GL_CALL;
2952 }
2954 #undef ASSERT_SYMBOL_PRESENT
2956 #ifdef MOZ_ENABLE_GL_TRACKING
2957 void CreatedProgram(GLContext *aOrigin, GLuint aName);
2958 void CreatedShader(GLContext *aOrigin, GLuint aName);
2959 void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
2960 void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
2961 void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
2962 void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
2963 void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
2964 void DeletedProgram(GLContext *aOrigin, GLuint aName);
2965 void DeletedShader(GLContext *aOrigin, GLuint aName);
2966 void DeletedBuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
2967 void DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
2968 void DeletedTextures(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
2969 void DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
2970 void DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
2972 void SharedContextDestroyed(GLContext *aChild);
2973 void ReportOutstandingNames();
2975 struct NamedResource {
2976 NamedResource()
2977 : origin(nullptr), name(0), originDeleted(false)
2978 { }
2980 NamedResource(GLContext *aOrigin, GLuint aName)
2981 : origin(aOrigin), name(aName), originDeleted(false)
2982 { }
2984 GLContext *origin;
2985 GLuint name;
2986 bool originDeleted;
2988 // for sorting
2989 bool operator<(const NamedResource& aOther) const {
2990 if (intptr_t(origin) < intptr_t(aOther.origin))
2991 return true;
2992 if (name < aOther.name)
2993 return true;
2994 return false;
2995 }
2996 bool operator==(const NamedResource& aOther) const {
2997 return origin == aOther.origin &&
2998 name == aOther.name &&
2999 originDeleted == aOther.originDeleted;
3000 }
3001 };
3003 nsTArray<NamedResource> mTrackedPrograms;
3004 nsTArray<NamedResource> mTrackedShaders;
3005 nsTArray<NamedResource> mTrackedTextures;
3006 nsTArray<NamedResource> mTrackedFramebuffers;
3007 nsTArray<NamedResource> mTrackedRenderbuffers;
3008 nsTArray<NamedResource> mTrackedBuffers;
3009 nsTArray<NamedResource> mTrackedQueries;
3010 #endif
3011 };
3013 bool DoesStringMatch(const char* aString, const char *aWantedString);
3016 } /* namespace gl */
3017 } /* namespace mozilla */
3019 #endif /* GLCONTEXT_H_ */