michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef GLCONTEXT_H_ michael@0: #define GLCONTEXT_H_ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #ifdef DEBUG michael@0: #include michael@0: #endif michael@0: michael@0: #ifdef WIN32 michael@0: #include michael@0: #endif michael@0: michael@0: #ifdef GetClassName michael@0: #undef GetClassName michael@0: #endif michael@0: michael@0: #include "GLDefs.h" michael@0: #include "GLLibraryLoader.h" michael@0: #include "gfx3DMatrix.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "plstr.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "GLContextTypes.h" michael@0: #include "GLTextureImage.h" michael@0: #include "SurfaceTypes.h" michael@0: #include "GLScreenBuffer.h" michael@0: #include "GLContextSymbols.h" michael@0: #include "mozilla/GenericRefCounted.h" michael@0: #include "mozilla/Scoped.h" michael@0: #include "gfx2DGlue.h" michael@0: michael@0: #ifdef DEBUG michael@0: #define MOZ_ENABLE_GL_TRACKING 1 michael@0: #endif michael@0: michael@0: class nsIntRegion; michael@0: class nsIRunnable; michael@0: class nsIThread; michael@0: michael@0: namespace android { michael@0: class GraphicBuffer; michael@0: } michael@0: michael@0: namespace mozilla { michael@0: namespace gfx { michael@0: class SourceSurface; michael@0: class DataSourceSurface; michael@0: struct SurfaceCaps; michael@0: } michael@0: michael@0: namespace gl { michael@0: class GLContext; michael@0: class GLLibraryEGL; michael@0: class GLScreenBuffer; michael@0: class TextureGarbageBin; michael@0: class GLBlitHelper; michael@0: class GLBlitTextureImageHelper; michael@0: class GLReadTexImageHelper; michael@0: class SharedSurface_GL; michael@0: } michael@0: michael@0: namespace layers { michael@0: class ColorTextureLayerProgram; michael@0: } michael@0: } michael@0: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(GLFeature) michael@0: bind_buffer_offset, michael@0: blend_minmax, michael@0: depth_texture, michael@0: draw_buffers, michael@0: draw_instanced, michael@0: draw_range_elements, michael@0: element_index_uint, michael@0: ES2_compatibility, michael@0: ES3_compatibility, michael@0: frag_color_float, michael@0: frag_depth, michael@0: framebuffer_blit, michael@0: framebuffer_multisample, michael@0: framebuffer_object, michael@0: get_query_object_iv, michael@0: instanced_arrays, michael@0: instanced_non_arrays, michael@0: occlusion_query, michael@0: occlusion_query_boolean, michael@0: occlusion_query2, michael@0: packed_depth_stencil, michael@0: query_objects, michael@0: renderbuffer_color_float, michael@0: renderbuffer_color_half_float, michael@0: robustness, michael@0: sRGB, michael@0: standard_derivatives, michael@0: texture_float, michael@0: texture_float_linear, michael@0: texture_half_float, michael@0: texture_half_float_linear, michael@0: texture_non_power_of_two, michael@0: transform_feedback, michael@0: vertex_array_object, michael@0: EnumMax michael@0: MOZ_END_ENUM_CLASS(GLFeature) michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t) michael@0: Unknown = 0, michael@0: OpenGL, // only for IsAtLeast's parameter michael@0: OpenGLCore, michael@0: OpenGLCompatibility, michael@0: OpenGLES michael@0: MOZ_END_ENUM_CLASS(ContextProfile) michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(GLVendor) michael@0: Intel, michael@0: NVIDIA, michael@0: ATI, michael@0: Qualcomm, michael@0: Imagination, michael@0: Nouveau, michael@0: Vivante, michael@0: VMware, michael@0: Other michael@0: MOZ_END_ENUM_CLASS(GLVendor) michael@0: michael@0: MOZ_BEGIN_ENUM_CLASS(GLRenderer) michael@0: Adreno200, michael@0: Adreno205, michael@0: AdrenoTM205, michael@0: AdrenoTM320, michael@0: SGX530, michael@0: SGX540, michael@0: Tegra, michael@0: AndroidEmulator, michael@0: GalliumLlvmpipe, michael@0: Other michael@0: MOZ_END_ENUM_CLASS(GLRenderer) michael@0: michael@0: class GLContext michael@0: : public GLLibraryLoader michael@0: , public GenericAtomicRefCounted michael@0: { michael@0: // ----------------------------------------------------------------------------- michael@0: // basic enums michael@0: public: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // basic getters michael@0: public: michael@0: michael@0: /** michael@0: * Returns true if the context is using ANGLE. This should only be overridden michael@0: * for an ANGLE implementation. michael@0: */ michael@0: virtual bool IsANGLE() const { michael@0: return false; michael@0: } michael@0: michael@0: /** michael@0: * Return true if we are running on a OpenGL core profile context michael@0: */ michael@0: inline bool IsCoreProfile() const { michael@0: MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile"); michael@0: michael@0: return mProfile == ContextProfile::OpenGLCore; michael@0: } michael@0: michael@0: /** michael@0: * Return true if we are running on a OpenGL compatibility profile context michael@0: * (legacy profile 2.1 on Max OS X) michael@0: */ michael@0: inline bool IsCompatibilityProfile() const { michael@0: MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile"); michael@0: michael@0: return mProfile == ContextProfile::OpenGLCompatibility; michael@0: } michael@0: michael@0: /** michael@0: * Return true if the context is a true OpenGL ES context or an ANGLE context michael@0: */ michael@0: inline bool IsGLES() const { michael@0: MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile"); michael@0: michael@0: return mProfile == ContextProfile::OpenGLES; michael@0: } michael@0: michael@0: static const char* GetProfileName(ContextProfile profile) michael@0: { michael@0: switch (profile) michael@0: { michael@0: case ContextProfile::OpenGL: michael@0: return "OpenGL"; michael@0: case ContextProfile::OpenGLCore: michael@0: return "OpenGL Core"; michael@0: case ContextProfile::OpenGLCompatibility: michael@0: return "OpenGL Compatibility"; michael@0: case ContextProfile::OpenGLES: michael@0: return "OpenGL ES"; michael@0: default: michael@0: break; michael@0: } michael@0: michael@0: MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile"); michael@0: return "OpenGL unknown profile"; michael@0: } michael@0: michael@0: /** michael@0: * Return true if we are running on a OpenGL core profile context michael@0: */ michael@0: const char* ProfileString() const { michael@0: return GetProfileName(mProfile); michael@0: } michael@0: michael@0: /** michael@0: * Return true if the context is compatible with given parameters michael@0: * michael@0: * IsAtLeast(ContextProfile::OpenGL, N) is exactly same as michael@0: * IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N) michael@0: */ michael@0: inline bool IsAtLeast(ContextProfile profile, unsigned int version) const michael@0: { michael@0: MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad parameter"); michael@0: MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile"); michael@0: MOZ_ASSERT(mVersion != 0, "unknown context version"); michael@0: michael@0: if (version > mVersion) { michael@0: return false; michael@0: } michael@0: michael@0: if (profile == ContextProfile::OpenGL) { michael@0: return profile == ContextProfile::OpenGLCore || michael@0: profile == ContextProfile::OpenGLCompatibility; michael@0: } michael@0: michael@0: return profile == mProfile; michael@0: } michael@0: michael@0: /** michael@0: * Return the version of the context. michael@0: * Example : michael@0: * If this a OpenGL 2.1, that will return 210 michael@0: */ michael@0: inline unsigned int Version() const { michael@0: return mVersion; michael@0: } michael@0: michael@0: const char* VersionString() const { michael@0: return mVersionString.get(); michael@0: } michael@0: michael@0: GLVendor Vendor() const { michael@0: return mVendor; michael@0: } michael@0: michael@0: GLRenderer Renderer() const { michael@0: return mRenderer; michael@0: } michael@0: michael@0: bool IsContextLost() const { michael@0: return mContextLost; michael@0: } michael@0: michael@0: /** michael@0: * If this context is double-buffered, returns TRUE. michael@0: */ michael@0: virtual bool IsDoubleBuffered() const { michael@0: return false; michael@0: } michael@0: michael@0: virtual GLContextType GetContextType() const = 0; michael@0: michael@0: virtual bool IsCurrent() = 0; michael@0: michael@0: protected: michael@0: michael@0: bool mInitialized; michael@0: bool mIsOffscreen; michael@0: bool mIsGlobalSharedContext; michael@0: bool mContextLost; michael@0: michael@0: /** michael@0: * mVersion store the OpenGL's version, multiplied by 100. For example, if michael@0: * the context is an OpenGL 2.1 context, mVersion value will be 210. michael@0: */ michael@0: unsigned int mVersion; michael@0: nsCString mVersionString; michael@0: ContextProfile mProfile; michael@0: michael@0: GLVendor mVendor; michael@0: GLRenderer mRenderer; michael@0: michael@0: inline void SetProfileVersion(ContextProfile profile, unsigned int version) { michael@0: MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!"); michael@0: MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion"); michael@0: MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion"); michael@0: michael@0: mVersion = version; michael@0: mProfile = profile; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Extensions management michael@0: /** michael@0: * This mechanism is designed to know if an extension is supported. In the long michael@0: * term, we would like to only use the extension group queries XXX_* to have michael@0: * full compatibility with context version and profiles (especialy the core that michael@0: * officialy don't bring any extensions). michael@0: */ michael@0: public: michael@0: michael@0: /** michael@0: * Known GL extensions that can be queried by michael@0: * IsExtensionSupported. The results of this are cached, and as michael@0: * such it's safe to use this even in performance critical code. michael@0: * If you add to this array, remember to add to the string names michael@0: * in GLContext.cpp. michael@0: */ michael@0: enum GLExtensions { michael@0: EXT_framebuffer_object, michael@0: ARB_framebuffer_object, michael@0: ARB_texture_rectangle, michael@0: EXT_bgra, michael@0: EXT_texture_format_BGRA8888, michael@0: OES_depth24, michael@0: OES_depth32, michael@0: OES_stencil8, michael@0: OES_texture_npot, michael@0: ARB_depth_texture, michael@0: OES_depth_texture, michael@0: OES_packed_depth_stencil, michael@0: IMG_read_format, michael@0: EXT_read_format_bgra, michael@0: APPLE_client_storage, michael@0: APPLE_texture_range, michael@0: ARB_texture_non_power_of_two, michael@0: ARB_pixel_buffer_object, michael@0: ARB_ES2_compatibility, michael@0: ARB_ES3_compatibility, michael@0: OES_texture_float, michael@0: OES_texture_float_linear, michael@0: ARB_texture_float, michael@0: OES_texture_half_float, michael@0: OES_texture_half_float_linear, michael@0: NV_half_float, michael@0: EXT_color_buffer_float, michael@0: EXT_color_buffer_half_float, michael@0: ARB_color_buffer_float, michael@0: EXT_unpack_subimage, michael@0: OES_standard_derivatives, michael@0: EXT_texture_filter_anisotropic, michael@0: EXT_texture_compression_s3tc, michael@0: EXT_texture_compression_dxt1, michael@0: ANGLE_texture_compression_dxt3, michael@0: ANGLE_texture_compression_dxt5, michael@0: AMD_compressed_ATC_texture, michael@0: IMG_texture_compression_pvrtc, michael@0: EXT_framebuffer_blit, michael@0: ANGLE_framebuffer_blit, michael@0: EXT_framebuffer_multisample, michael@0: ANGLE_framebuffer_multisample, michael@0: OES_rgb8_rgba8, michael@0: ARB_robustness, michael@0: EXT_robustness, michael@0: ARB_sync, michael@0: OES_EGL_image, michael@0: OES_EGL_sync, michael@0: OES_EGL_image_external, michael@0: EXT_packed_depth_stencil, michael@0: OES_element_index_uint, michael@0: OES_vertex_array_object, michael@0: ARB_vertex_array_object, michael@0: APPLE_vertex_array_object, michael@0: ARB_draw_buffers, michael@0: EXT_draw_buffers, michael@0: EXT_gpu_shader4, michael@0: EXT_blend_minmax, michael@0: ARB_draw_instanced, michael@0: EXT_draw_instanced, michael@0: NV_draw_instanced, michael@0: ARB_instanced_arrays, michael@0: NV_instanced_arrays, michael@0: ANGLE_instanced_arrays, michael@0: EXT_occlusion_query_boolean, michael@0: ARB_occlusion_query2, michael@0: EXT_transform_feedback, michael@0: NV_transform_feedback, michael@0: ANGLE_depth_texture, michael@0: EXT_sRGB, michael@0: EXT_texture_sRGB, michael@0: ARB_framebuffer_sRGB, michael@0: EXT_framebuffer_sRGB, michael@0: KHR_debug, michael@0: ARB_half_float_pixel, michael@0: EXT_frag_depth, michael@0: OES_compressed_ETC1_RGB8_texture, michael@0: EXT_draw_range_elements, michael@0: Extensions_Max, michael@0: Extensions_End michael@0: }; michael@0: michael@0: bool IsExtensionSupported(GLExtensions aKnownExtension) const { michael@0: return mAvailableExtensions[aKnownExtension]; michael@0: } michael@0: michael@0: void MarkExtensionUnsupported(GLExtensions aKnownExtension) { michael@0: mAvailableExtensions[aKnownExtension] = 0; michael@0: } michael@0: michael@0: void MarkExtensionSupported(GLExtensions aKnownExtension) { michael@0: mAvailableExtensions[aKnownExtension] = 1; michael@0: } michael@0: michael@0: michael@0: public: michael@0: michael@0: template michael@0: static void InitializeExtensionsBitSet(std::bitset& extensionsBitset, const char* extStr, const char** extList, bool verbose = false) michael@0: { michael@0: char* exts = ::strdup(extStr); michael@0: michael@0: if (verbose) michael@0: printf_stderr("Extensions: %s\n", exts); michael@0: michael@0: char* cur = exts; michael@0: bool done = false; michael@0: while (!done) { michael@0: char* space = strchr(cur, ' '); michael@0: if (space) { michael@0: *space = '\0'; michael@0: } else { michael@0: done = true; michael@0: } michael@0: michael@0: for (int i = 0; extList[i]; ++i) { michael@0: if (PL_strcasecmp(cur, extList[i]) == 0) { michael@0: if (verbose) michael@0: printf_stderr("Found extension %s\n", cur); michael@0: extensionsBitset[i] = true; michael@0: } michael@0: } michael@0: michael@0: cur = space + 1; michael@0: } michael@0: michael@0: free(exts); michael@0: } michael@0: michael@0: michael@0: protected: michael@0: std::bitset mAvailableExtensions; michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Feature queries michael@0: /* michael@0: * This mecahnism introduces a new way to check if a OpenGL feature is michael@0: * supported, regardless of whether it is supported by an extension or natively michael@0: * by the context version/profile michael@0: */ michael@0: public: michael@0: bool IsSupported(GLFeature feature) const { michael@0: return mAvailableFeatures[size_t(feature)]; michael@0: } michael@0: michael@0: static const char* GetFeatureName(GLFeature feature); michael@0: michael@0: michael@0: private: michael@0: std::bitset mAvailableFeatures; michael@0: michael@0: /** michael@0: * Init features regarding OpenGL extension and context version and profile michael@0: */ michael@0: void InitFeatures(); michael@0: michael@0: /** michael@0: * Mark the feature and associated extensions as unsupported michael@0: */ michael@0: void MarkUnsupported(GLFeature feature); michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Robustness handling michael@0: public: michael@0: michael@0: bool HasRobustness() const { michael@0: return mHasRobustness; michael@0: } michael@0: michael@0: /** michael@0: * The derived class is expected to provide information on whether or not it michael@0: * supports robustness. michael@0: */ michael@0: virtual bool SupportsRobustness() const = 0; michael@0: michael@0: michael@0: private: michael@0: bool mHasRobustness; michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Error handling michael@0: public: michael@0: michael@0: static const char* GLErrorToString(GLenum aError) michael@0: { michael@0: switch (aError) { michael@0: case LOCAL_GL_INVALID_ENUM: michael@0: return "GL_INVALID_ENUM"; michael@0: case LOCAL_GL_INVALID_VALUE: michael@0: return "GL_INVALID_VALUE"; michael@0: case LOCAL_GL_INVALID_OPERATION: michael@0: return "GL_INVALID_OPERATION"; michael@0: case LOCAL_GL_STACK_OVERFLOW: michael@0: return "GL_STACK_OVERFLOW"; michael@0: case LOCAL_GL_STACK_UNDERFLOW: michael@0: return "GL_STACK_UNDERFLOW"; michael@0: case LOCAL_GL_OUT_OF_MEMORY: michael@0: return "GL_OUT_OF_MEMORY"; michael@0: case LOCAL_GL_TABLE_TOO_LARGE: michael@0: return "GL_TABLE_TOO_LARGE"; michael@0: case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION: michael@0: return "GL_INVALID_FRAMEBUFFER_OPERATION"; michael@0: default: michael@0: return ""; michael@0: } michael@0: } michael@0: michael@0: michael@0: /** \returns the first GL error, and guarantees that all GL error flags are cleared, michael@0: * i.e. that a subsequent GetError call will return NO_ERROR michael@0: */ michael@0: GLenum GetAndClearError() michael@0: { michael@0: // the first error is what we want to return michael@0: GLenum error = fGetError(); michael@0: michael@0: if (error) { michael@0: // clear all pending errors michael@0: while(fGetError()) {} michael@0: } michael@0: michael@0: return error; michael@0: } michael@0: michael@0: michael@0: /*** In GL debug mode, we completely override glGetError ***/ michael@0: michael@0: GLenum fGetError() michael@0: { michael@0: #ifdef DEBUG michael@0: // debug mode ends up eating the error in AFTER_GL_CALL michael@0: if (DebugMode()) { michael@0: GLenum err = mGLError; michael@0: mGLError = LOCAL_GL_NO_ERROR; michael@0: return err; michael@0: } michael@0: #endif // DEBUG michael@0: michael@0: return mSymbols.fGetError(); michael@0: } michael@0: michael@0: michael@0: #ifdef DEBUG michael@0: private: michael@0: michael@0: GLenum mGLError; michael@0: #endif // DEBUG michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // MOZ_GL_DEBUG implementation michael@0: private: michael@0: michael@0: #undef BEFORE_GL_CALL michael@0: #undef AFTER_GL_CALL michael@0: michael@0: #ifdef MOZ_ENABLE_GL_TRACKING michael@0: michael@0: #ifndef MOZ_FUNCTION_NAME michael@0: # ifdef __GNUC__ michael@0: # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__ michael@0: # elif defined(_MSC_VER) michael@0: # define MOZ_FUNCTION_NAME __FUNCTION__ michael@0: # else michael@0: # define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name. michael@0: # endif michael@0: #endif michael@0: michael@0: void BeforeGLCall(const char* glFunction) michael@0: { michael@0: MOZ_ASSERT(IsCurrent()); michael@0: if (DebugMode()) { michael@0: GLContext *currentGLContext = nullptr; michael@0: michael@0: currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS); michael@0: michael@0: if (DebugMode() & DebugTrace) michael@0: printf_stderr("[gl:%p] > %s\n", this, glFunction); michael@0: if (this != currentGLContext) { michael@0: printf_stderr("Fatal: %s called on non-current context %p. " michael@0: "The current context for this thread is %p.\n", michael@0: glFunction, this, currentGLContext); michael@0: NS_ABORT(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: void AfterGLCall(const char* glFunction) michael@0: { michael@0: if (DebugMode()) { michael@0: // calling fFinish() immediately after every GL call makes sure that if this GL command crashes, michael@0: // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces michael@0: // tend to be meaningless michael@0: mSymbols.fFinish(); michael@0: mGLError = mSymbols.fGetError(); michael@0: if (DebugMode() & DebugTrace) michael@0: printf_stderr("[gl:%p] < %s [0x%04x]\n", this, glFunction, mGLError); michael@0: if (mGLError != LOCAL_GL_NO_ERROR) { michael@0: printf_stderr("GL ERROR: %s generated GL error %s(0x%04x)\n", michael@0: glFunction, michael@0: GLErrorToString(mGLError), michael@0: mGLError); michael@0: if (DebugMode() & DebugAbortOnError) michael@0: NS_ABORT(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: GLContext *TrackingContext() michael@0: { michael@0: GLContext *tip = this; michael@0: while (tip->mSharedContext) michael@0: tip = tip->mSharedContext; michael@0: return tip; michael@0: } michael@0: michael@0: #define BEFORE_GL_CALL \ michael@0: do { \ michael@0: BeforeGLCall(MOZ_FUNCTION_NAME); \ michael@0: } while (0) michael@0: michael@0: #define AFTER_GL_CALL \ michael@0: do { \ michael@0: AfterGLCall(MOZ_FUNCTION_NAME); \ michael@0: } while (0) michael@0: michael@0: #define TRACKING_CONTEXT(a) \ michael@0: do { \ michael@0: TrackingContext()->a; \ michael@0: } while (0) michael@0: michael@0: #else // ifdef DEBUG michael@0: michael@0: #define BEFORE_GL_CALL do { } while (0) michael@0: #define AFTER_GL_CALL do { } while (0) michael@0: #define TRACKING_CONTEXT(a) do {} while (0) michael@0: michael@0: #endif // ifdef DEBUG michael@0: michael@0: #define ASSERT_SYMBOL_PRESENT(func) \ michael@0: do {\ michael@0: MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\ michael@0: if (MOZ_UNLIKELY(!mSymbols.func)) {\ michael@0: printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\ michael@0: MOZ_CRASH();\ michael@0: }\ michael@0: } while (0) michael@0: michael@0: // Do whatever setup is necessary to draw to our offscreen FBO, if it's michael@0: // bound. michael@0: void BeforeGLDrawCall() { michael@0: } michael@0: michael@0: // Do whatever tear-down is necessary after drawing to our offscreen FBO, michael@0: // if it's bound. michael@0: void AfterGLDrawCall() michael@0: { michael@0: if (mScreen) michael@0: mScreen->AfterDrawCall(); michael@0: } michael@0: michael@0: // Do whatever setup is necessary to read from our offscreen FBO, if it's michael@0: // bound. michael@0: void BeforeGLReadCall() michael@0: { michael@0: if (mScreen) michael@0: mScreen->BeforeReadCall(); michael@0: } michael@0: michael@0: // Do whatever tear-down is necessary after reading from our offscreen FBO, michael@0: // if it's bound. michael@0: void AfterGLReadCall() { michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // GL official entry points michael@0: public: michael@0: michael@0: void fActiveTexture(GLenum texture) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fActiveTexture(texture); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fAttachShader(GLuint program, GLuint shader) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fAttachShader(program, shader); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBeginQuery(GLenum target, GLuint id) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBeginQuery); michael@0: mSymbols.fBeginQuery(target, id); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBindAttribLocation(program, index, name); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBindBuffer(GLenum target, GLuint buffer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBindBuffer(target, buffer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBindFramebuffer(GLenum target, GLuint framebuffer) { michael@0: if (!mScreen) { michael@0: raw_fBindFramebuffer(target, framebuffer); michael@0: return; michael@0: } michael@0: michael@0: switch (target) { michael@0: case LOCAL_GL_DRAW_FRAMEBUFFER_EXT: michael@0: mScreen->BindDrawFB(framebuffer); michael@0: return; michael@0: michael@0: case LOCAL_GL_READ_FRAMEBUFFER_EXT: michael@0: mScreen->BindReadFB(framebuffer); michael@0: return; michael@0: michael@0: case LOCAL_GL_FRAMEBUFFER: michael@0: mScreen->BindFB(framebuffer); michael@0: return; michael@0: michael@0: default: michael@0: // Nothing we care about, likely an error. michael@0: break; michael@0: } michael@0: michael@0: raw_fBindFramebuffer(target, framebuffer); michael@0: } michael@0: michael@0: void fBindTexture(GLenum target, GLuint texture) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBindTexture(target, texture); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBlendColor(red, green, blue, alpha); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBlendEquation(GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBlendEquation(mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBlendFunc(GLenum sfactor, GLenum dfactor) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBlendFunc(sfactor, dfactor); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBufferData(target, size, data, usage); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { michael@0: raw_fBufferData(target, size, data, usage); michael@0: michael@0: // bug 744888 michael@0: if (WorkAroundDriverBugs() && michael@0: !data && michael@0: Vendor() == GLVendor::NVIDIA) michael@0: { michael@0: char c = 0; michael@0: fBufferSubData(target, size-1, 1, &c); michael@0: } michael@0: } michael@0: michael@0: void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBufferSubData(target, offset, size, data); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fClear(GLbitfield mask) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fClear(mask); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fClear(GLbitfield mask) { michael@0: BeforeGLDrawCall(); michael@0: raw_fClear(mask); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fClearColor(r, g, b, a); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fClearStencil(GLint s) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fClearStencil(s); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fClientActiveTexture(GLenum texture) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fClientActiveTexture(texture); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fColorMask(red, green, blue, alpha); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *pixels) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { michael@0: if (!IsTextureSizeSafeToPassToDriver(target, width, height)) { michael@0: // pass wrong values to cause the GL to generate GL_INVALID_VALUE. michael@0: // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver. michael@0: level = -1; michael@0: width = -1; michael@0: height = -1; michael@0: border = -1; michael@0: } michael@0: michael@0: BeforeGLReadCall(); michael@0: raw_fCopyTexImage2D(target, level, internalformat, michael@0: x, y, width, height, border); michael@0: AfterGLReadCall(); michael@0: } michael@0: michael@0: void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { michael@0: BeforeGLReadCall(); michael@0: raw_fCopyTexSubImage2D(target, level, xoffset, yoffset, michael@0: x, y, width, height); michael@0: AfterGLReadCall(); michael@0: } michael@0: michael@0: void fCullFace(GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCullFace(mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDebugMessageCallback); michael@0: mSymbols.fDebugMessageCallback(callback, userParam); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDebugMessageControl); michael@0: mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDebugMessageInsert); michael@0: mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDetachShader(GLuint program, GLuint shader) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDetachShader(program, shader); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDepthFunc(GLenum func) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDepthFunc(func); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDepthMask(realGLboolean flag) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDepthMask(flag); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDisable(GLenum capability) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDisable(capability); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDisableClientState(GLenum capability) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDisableClientState(capability); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDisableVertexAttribArray(GLuint index) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDisableVertexAttribArray(index); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDrawBuffer(GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDrawBuffer(mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDrawArrays(mode, first, count); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDrawElements(mode, count, type, indices); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fDrawArrays(GLenum mode, GLint first, GLsizei count) { michael@0: BeforeGLDrawCall(); michael@0: raw_fDrawArrays(mode, first, count); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { michael@0: BeforeGLDrawCall(); michael@0: raw_fDrawElements(mode, count, type, indices); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: void fEnable(GLenum capability) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fEnable(capability); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fEnableClientState(GLenum capability) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fEnableClientState(capability); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fEnableVertexAttribArray(GLuint index) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fEnableVertexAttribArray(index); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fEndQuery(GLenum target) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fEndQuery); michael@0: mSymbols.fEndQuery(target); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fFinish() { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fFinish(); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fFlush() { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fFlush(); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fFrontFace(GLenum face) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fFrontFace(face); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetAttachedShaders(program, maxCount, count, shaders); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: GLint fGetAttribLocation(GLuint program, const GLchar* name) { michael@0: BEFORE_GL_CALL; michael@0: GLint retval = mSymbols.fGetAttribLocation(program, name); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: private: michael@0: void raw_fGetIntegerv(GLenum pname, GLint *params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetIntegerv(pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: michael@0: void fGetIntegerv(GLenum pname, GLint *params) { michael@0: switch (pname) michael@0: { michael@0: // LOCAL_GL_FRAMEBUFFER_BINDING is equal to michael@0: // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, michael@0: // so we don't need two cases. michael@0: case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT: michael@0: if (mScreen) { michael@0: *params = mScreen->GetDrawFB(); michael@0: } else { michael@0: raw_fGetIntegerv(pname, params); michael@0: } michael@0: break; michael@0: michael@0: case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT: michael@0: if (mScreen) { michael@0: *params = mScreen->GetReadFB(); michael@0: } else { michael@0: raw_fGetIntegerv(pname, params); michael@0: } michael@0: break; michael@0: michael@0: case LOCAL_GL_MAX_TEXTURE_SIZE: michael@0: MOZ_ASSERT(mMaxTextureSize>0); michael@0: *params = mMaxTextureSize; michael@0: break; michael@0: michael@0: case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: michael@0: MOZ_ASSERT(mMaxCubeMapTextureSize>0); michael@0: *params = mMaxCubeMapTextureSize; michael@0: break; michael@0: michael@0: case LOCAL_GL_MAX_RENDERBUFFER_SIZE: michael@0: MOZ_ASSERT(mMaxRenderbufferSize>0); michael@0: *params = mMaxRenderbufferSize; michael@0: break; michael@0: michael@0: case LOCAL_GL_VIEWPORT: michael@0: for (size_t i = 0; i < 4; i++) { michael@0: params[i] = mViewportRect[i]; michael@0: } michael@0: break; michael@0: michael@0: case LOCAL_GL_SCISSOR_BOX: michael@0: for (size_t i = 0; i < 4; i++) { michael@0: params[i] = mScissorRect[i]; michael@0: } michael@0: break; michael@0: michael@0: default: michael@0: raw_fGetIntegerv(pname, params); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: void GetUIntegerv(GLenum pname, GLuint *params) { michael@0: fGetIntegerv(pname, reinterpret_cast(params)); michael@0: } michael@0: michael@0: void fGetFloatv(GLenum pname, GLfloat *params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetFloatv(pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetBooleanv(GLenum pname, realGLboolean *params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetBooleanv(pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetBufferParameteriv(target, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog); michael@0: GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: void fGetPointerv(GLenum pname, GLvoid** params) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetPointerv); michael@0: mSymbols.fGetPointerv(pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetObjectLabel); michael@0: mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel); michael@0: mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGenerateMipmap(GLenum target) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGenerateMipmap(target); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetProgramiv(GLuint program, GLenum pname, GLint* param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetProgramiv(program, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexParameteri(GLenum target, GLenum pname, GLint param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexParameteri(target, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexParameteriv(target, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexParameterf(GLenum target, GLenum pname, GLfloat param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexParameterf(target, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: const GLubyte* fGetString(GLenum name) { michael@0: BEFORE_GL_CALL; michael@0: const GLubyte *result = mSymbols.fGetString(name); michael@0: AFTER_GL_CALL; michael@0: return result; michael@0: } michael@0: michael@0: void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetTexImage); michael@0: mSymbols.fGetTexImage(target, level, format, type, img); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv); michael@0: mSymbols.fGetTexLevelParameteriv(target, level, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetTexParameterfv(target, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetTexParameteriv(target, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetUniformfv(GLuint program, GLint location, GLfloat* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetUniformfv(program, location, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetUniformiv(GLuint program, GLint location, GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetUniformiv(program, location, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: GLint fGetUniformLocation (GLint programObj, const GLchar* name) { michael@0: BEFORE_GL_CALL; michael@0: GLint retval = mSymbols.fGetUniformLocation(programObj, name); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetVertexAttribfv(index, pname, retval); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetVertexAttribiv(index, pname, retval); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetVertexAttribPointerv(index, pname, retval); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fHint(GLenum target, GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fHint(target, mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: realGLboolean fIsBuffer(GLuint buffer) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsBuffer(buffer); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: realGLboolean fIsEnabled(GLenum capability) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsEnabled(capability); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: realGLboolean fIsProgram(GLuint program) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsProgram(program); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: realGLboolean fIsShader(GLuint shader) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsShader(shader); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: realGLboolean fIsTexture(GLuint texture) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsTexture(texture); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: void fLineWidth(GLfloat width) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fLineWidth(width); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fLinkProgram(GLuint program) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fLinkProgram(program); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fObjectLabel); michael@0: mSymbols.fObjectLabel(identifier, name, length, label); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fObjectPtrLabel); michael@0: mSymbols.fObjectPtrLabel(ptr, length, label); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fLoadIdentity() { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fLoadIdentity(); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fLoadMatrixf(const GLfloat *matrix) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fLoadMatrixf(matrix); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fMatrixMode(GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fMatrixMode(mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fPixelStorei(GLenum pname, GLint param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fPixelStorei(pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid *pointer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTextureRangeAPPLE(target, length, pointer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fPointParameterf(GLenum pname, GLfloat param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fPointParameterf(pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fPolygonOffset(GLfloat factor, GLfloat bias) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fPolygonOffset(factor, bias); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fPopDebugGroup() { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fPopDebugGroup); michael@0: mSymbols.fPopDebugGroup(); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fPushDebugGroup); michael@0: mSymbols.fPushDebugGroup(source, id, length, message); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fReadBuffer(GLenum mode) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fReadBuffer(mode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fReadPixels(x, y, width, height, format, type, pixels); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { michael@0: BeforeGLReadCall(); michael@0: michael@0: bool didReadPixels = false; michael@0: if (mScreen) { michael@0: didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels); michael@0: } michael@0: michael@0: if (!didReadPixels) { michael@0: raw_fReadPixels(x, y, width, height, format, type, pixels); michael@0: } michael@0: michael@0: AfterGLReadCall(); michael@0: } michael@0: michael@0: public: michael@0: void fSampleCoverage(GLclampf value, realGLboolean invert) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fSampleCoverage(value, invert); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) { michael@0: if (mScissorRect[0] == x && michael@0: mScissorRect[1] == y && michael@0: mScissorRect[2] == width && michael@0: mScissorRect[3] == height) michael@0: { michael@0: return; michael@0: } michael@0: mScissorRect[0] = x; michael@0: mScissorRect[1] = y; michael@0: mScissorRect[2] = width; michael@0: mScissorRect[3] = height; michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fScissor(x, y, width, height); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilFunc(GLenum func, GLint ref, GLuint mask) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilFunc(func, ref, mask); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilFuncSeparate(frontfunc, backfunc, ref, mask); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilMask(GLuint mask) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilMask(mask); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilMaskSeparate(GLenum face, GLuint mask) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilMaskSeparate(face, mask); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilOp(fail, zfail, zpass); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexGeni(GLenum coord, GLenum pname, GLint param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexGeni(coord, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexGenf(GLenum coord, GLenum pname, GLfloat param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexGenf(coord, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexGenfv(coord, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { michael@0: if (!IsTextureSizeSafeToPassToDriver(target, width, height)) { michael@0: // pass wrong values to cause the GL to generate GL_INVALID_VALUE. michael@0: // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver. michael@0: level = -1; michael@0: width = -1; michael@0: height = -1; michael@0: border = -1; michael@0: } michael@0: raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); michael@0: } michael@0: michael@0: void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform1f(GLint location, GLfloat v0) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform1f(location, v0); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform1fv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform1i(GLint location, GLint v0) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform1i(location, v0); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform1iv(GLint location, GLsizei count, const GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform1iv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform2f(GLint location, GLfloat v0, GLfloat v1) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform2f(location, v0, v1); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform2fv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform2i(GLint location, GLint v0, GLint v1) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform2i(location, v0, v1); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform2iv(GLint location, GLsizei count, const GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform2iv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform3f(location, v0, v1, v2); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform3fv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform3i(location, v0, v1, v2); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform3iv(GLint location, GLsizei count, const GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform3iv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform4f(location, v0, v1, v2, v3); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform4fv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform4i(location, v0, v1, v2, v3); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniform4iv(GLint location, GLsizei count, const GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniform4iv(location, count, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniformMatrix2fv(location, count, transpose, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniformMatrix3fv(location, count, transpose, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUniformMatrix4fv(location, count, transpose, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fUseProgram(GLuint program) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fUseProgram(program); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fValidateProgram(GLuint program) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fValidateProgram(program); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib1f(GLuint index, GLfloat x) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib1f(index, x); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib2f(index, x, y); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib3f(index, x, y, z); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib4f(index, x, y, z, w); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib1fv(GLuint index, const GLfloat* v) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib1fv(index, v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib2fv(GLuint index, const GLfloat* v) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib2fv(index, v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib3fv(GLuint index, const GLfloat* v) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib3fv(index, v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexAttrib4fv(GLuint index, const GLfloat* v) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexAttrib4fv(index, v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fVertexPointer(size, type, stride, pointer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fCompileShader(GLuint shader) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCompileShader(shader); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetShaderiv(shader, pname, param); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { michael@0: MOZ_ASSERT(IsGLES()); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat); michael@0: mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { michael@0: if (IsGLES()) { michael@0: raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); michael@0: } else { michael@0: // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions. michael@0: GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision); michael@0: } michael@0: } michael@0: michael@0: void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetShaderSource(obj, maxLength, length, source); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fShaderSource(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fShaderSource(shader, count, strings, lengths); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBindFramebuffer(target, framebuffer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fBindRenderbuffer(GLenum target, GLuint renderbuffer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fBindRenderbuffer(target, renderbuffer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: GLenum fCheckFramebufferStatus(GLenum target) { michael@0: BEFORE_GL_CALL; michael@0: GLenum retval = mSymbols.fCheckFramebufferStatus(target); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGetRenderbufferParameteriv(target, pname, value); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: realGLboolean fIsFramebuffer (GLuint framebuffer) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: public: michael@0: realGLboolean fIsRenderbuffer (GLuint renderbuffer) { michael@0: BEFORE_GL_CALL; michael@0: realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fRenderbufferStorage(target, internalFormat, width, height); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: private: michael@0: void raw_fDepthRange(GLclampf a, GLclampf b) { michael@0: MOZ_ASSERT(!IsGLES()); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDepthRange); michael@0: mSymbols.fDepthRange(a, b); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDepthRangef(GLclampf a, GLclampf b) { michael@0: MOZ_ASSERT(IsGLES()); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDepthRangef); michael@0: mSymbols.fDepthRangef(a, b); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fClearDepth(GLclampf v) { michael@0: MOZ_ASSERT(!IsGLES()); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fClearDepth); michael@0: mSymbols.fClearDepth(v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fClearDepthf(GLclampf v) { michael@0: MOZ_ASSERT(IsGLES()); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fClearDepthf); michael@0: mSymbols.fClearDepthf(v); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: void fDepthRange(GLclampf a, GLclampf b) { michael@0: if (IsGLES()) { michael@0: raw_fDepthRangef(a, b); michael@0: } else { michael@0: raw_fDepthRange(a, b); michael@0: } michael@0: } michael@0: michael@0: void fClearDepth(GLclampf v) { michael@0: if (IsGLES()) { michael@0: raw_fClearDepthf(v); michael@0: } else { michael@0: raw_fClearDepth(v); michael@0: } michael@0: } michael@0: michael@0: void* fMapBuffer(GLenum target, GLenum access) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fMapBuffer); michael@0: void *ret = mSymbols.fMapBuffer(target, access); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: realGLboolean fUnmapBuffer(GLenum target) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fUnmapBuffer); michael@0: realGLboolean ret = mSymbols.fUnmapBuffer(target); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: michael@0: private: michael@0: GLuint raw_fCreateProgram() { michael@0: BEFORE_GL_CALL; michael@0: GLuint ret = mSymbols.fCreateProgram(); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: GLuint raw_fCreateShader(GLenum t) { michael@0: BEFORE_GL_CALL; michael@0: GLuint ret = mSymbols.fCreateShader(t); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: void raw_fGenBuffers(GLsizei n, GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGenBuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fGenFramebuffers(GLsizei n, GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGenFramebuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fGenRenderbuffers(GLsizei n, GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGenRenderbuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fGenTextures(GLsizei n, GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fGenTextures(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: GLuint fCreateProgram() { michael@0: GLuint ret = raw_fCreateProgram(); michael@0: TRACKING_CONTEXT(CreatedProgram(this, ret)); michael@0: return ret; michael@0: } michael@0: michael@0: GLuint fCreateShader(GLenum t) { michael@0: GLuint ret = raw_fCreateShader(t); michael@0: TRACKING_CONTEXT(CreatedShader(this, ret)); michael@0: return ret; michael@0: } michael@0: michael@0: void fGenBuffers(GLsizei n, GLuint* names) { michael@0: raw_fGenBuffers(n, names); michael@0: TRACKING_CONTEXT(CreatedBuffers(this, n, names)); michael@0: } michael@0: michael@0: void fGenFramebuffers(GLsizei n, GLuint* names) { michael@0: raw_fGenFramebuffers(n, names); michael@0: TRACKING_CONTEXT(CreatedFramebuffers(this, n, names)); michael@0: } michael@0: michael@0: void fGenRenderbuffers(GLsizei n, GLuint* names) { michael@0: raw_fGenRenderbuffers(n, names); michael@0: TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names)); michael@0: } michael@0: michael@0: void fGenTextures(GLsizei n, GLuint* names) { michael@0: raw_fGenTextures(n, names); michael@0: TRACKING_CONTEXT(CreatedTextures(this, n, names)); michael@0: } michael@0: michael@0: private: michael@0: void raw_fDeleteProgram(GLuint program) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteProgram(program); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDeleteShader(GLuint shader) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteShader(shader); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDeleteBuffers(GLsizei n, const GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteBuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteFramebuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteRenderbuffers(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDeleteTextures(GLsizei n, const GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDeleteTextures(n, names); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: public: michael@0: michael@0: void fDeleteProgram(GLuint program) { michael@0: raw_fDeleteProgram(program); michael@0: TRACKING_CONTEXT(DeletedProgram(this, program)); michael@0: } michael@0: michael@0: void fDeleteShader(GLuint shader) { michael@0: raw_fDeleteShader(shader); michael@0: TRACKING_CONTEXT(DeletedShader(this, shader)); michael@0: } michael@0: michael@0: void fDeleteBuffers(GLsizei n, const GLuint* names) { michael@0: raw_fDeleteBuffers(n, names); michael@0: TRACKING_CONTEXT(DeletedBuffers(this, n, names)); michael@0: } michael@0: michael@0: void fDeleteFramebuffers(GLsizei n, const GLuint* names) { michael@0: if (mScreen) { michael@0: // Notify mScreen which framebuffers we're deleting. michael@0: // Otherwise, we will get framebuffer binding mispredictions. michael@0: for (int i = 0; i < n; i++) { michael@0: mScreen->DeletingFB(names[i]); michael@0: } michael@0: } michael@0: michael@0: if (n == 1 && *names == 0) { michael@0: // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228. michael@0: } else { michael@0: raw_fDeleteFramebuffers(n, names); michael@0: } michael@0: TRACKING_CONTEXT(DeletedFramebuffers(this, n, names)); michael@0: } michael@0: michael@0: void fDeleteRenderbuffers(GLsizei n, const GLuint* names) { michael@0: raw_fDeleteRenderbuffers(n, names); michael@0: TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names)); michael@0: } michael@0: michael@0: void fDeleteTextures(GLsizei n, const GLuint* names) { michael@0: raw_fDeleteTextures(n, names); michael@0: TRACKING_CONTEXT(DeletedTextures(this, n, names)); michael@0: } michael@0: michael@0: GLenum fGetGraphicsResetStatus() { michael@0: MOZ_ASSERT(mHasRobustness); michael@0: michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus); michael@0: GLenum ret = mSymbols.fGetGraphicsResetStatus(); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Extension ARB_sync (GL) michael@0: public: michael@0: GLsync fFenceSync(GLenum condition, GLbitfield flags) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fFenceSync); michael@0: GLsync ret = mSymbols.fFenceSync(condition, flags); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: realGLboolean fIsSync(GLsync sync) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fIsSync); michael@0: realGLboolean ret = mSymbols.fIsSync(sync); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: void fDeleteSync(GLsync sync) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDeleteSync); michael@0: mSymbols.fDeleteSync(sync); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fClientWaitSync); michael@0: GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fWaitSync); michael@0: mSymbols.fWaitSync(sync, flags, timeout); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetInteger64v(GLenum pname, GLint64 *params) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetInteger64v); michael@0: mSymbols.fGetInteger64v(pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetSynciv); michael@0: mSymbols.fGetSynciv(sync, pname, bufSize, length, values); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Extension OES_EGL_image (GLES) michael@0: public: michael@0: void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D); michael@0: mSymbols.fEGLImageTargetTexture2D(target, image); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage); michael@0: mSymbols.fEGLImageTargetRenderbufferStorage(target, image); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_bind_buffer_offset michael@0: public: michael@0: void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBindBufferOffset); michael@0: mSymbols.fBindBufferOffset(target, index, buffer, offset); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_draw_buffers michael@0: public: michael@0: void fDrawBuffers(GLsizei n, const GLenum* bufs) { michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fDrawBuffers(n, bufs); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_draw_instanced michael@0: public: michael@0: void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) michael@0: { michael@0: BeforeGLDrawCall(); michael@0: raw_fDrawArraysInstanced(mode, first, count, primcount); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount) michael@0: { michael@0: BeforeGLDrawCall(); michael@0: raw_fDrawElementsInstanced(mode, count, type, indices, primcount); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: private: michael@0: void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced); michael@0: mSymbols.fDrawArraysInstanced(mode, first, count, primcount); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced); michael@0: mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Feature draw_range_elements michael@0: public: michael@0: void fDrawRangeElements(GLenum mode, GLuint start, GLuint end, michael@0: GLsizei count, GLenum type, const GLvoid* indices) michael@0: { michael@0: BeforeGLDrawCall(); michael@0: raw_fDrawRangeElements(mode, start, end, count, type, indices); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: private: michael@0: void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end, michael@0: GLsizei count, GLenum type, const GLvoid* indices) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDrawRangeElements); michael@0: mSymbols.fDrawRangeElements(mode, start, end, count, type, indices); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_framebuffer_blit michael@0: public: michael@0: // Draw/Read michael@0: void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { michael@0: BeforeGLDrawCall(); michael@0: BeforeGLReadCall(); michael@0: raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); michael@0: AfterGLReadCall(); michael@0: AfterGLDrawCall(); michael@0: } michael@0: michael@0: michael@0: private: michael@0: void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBlitFramebuffer); michael@0: mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_framebuffer_multisample michael@0: public: michael@0: void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample); michael@0: mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_instanced_arrays michael@0: public: michael@0: void fVertexAttribDivisor(GLuint index, GLuint divisor) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor); michael@0: mSymbols.fVertexAttribDivisor(index, divisor); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_query_objects michael@0: /** michael@0: * XXX_query_objects: michael@0: * - provide all followed entry points michael@0: * michael@0: * XXX_occlusion_query2: michael@0: * - depends on XXX_query_objects michael@0: * - provide ANY_SAMPLES_PASSED michael@0: * michael@0: * XXX_occlusion_query_boolean: michael@0: * - depends on XXX_occlusion_query2 michael@0: * - provide ANY_SAMPLES_PASSED_CONSERVATIVE michael@0: */ michael@0: public: michael@0: void fDeleteQueries(GLsizei n, const GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDeleteQueries); michael@0: mSymbols.fDeleteQueries(n, names); michael@0: AFTER_GL_CALL; michael@0: TRACKING_CONTEXT(DeletedQueries(this, n, names)); michael@0: } michael@0: michael@0: void fGenQueries(GLsizei n, GLuint* names) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGenQueries); michael@0: mSymbols.fGenQueries(n, names); michael@0: AFTER_GL_CALL; michael@0: TRACKING_CONTEXT(CreatedQueries(this, n, names)); michael@0: } michael@0: michael@0: void fGetQueryiv(GLenum target, GLenum pname, GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetQueryiv); michael@0: mSymbols.fGetQueryiv(target, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv); michael@0: mSymbols.fGetQueryObjectuiv(id, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: realGLboolean fIsQuery(GLuint query) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fIsQuery); michael@0: realGLboolean retval = mSymbols.fIsQuery(query); michael@0: AFTER_GL_CALL; michael@0: return retval; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_get_query_object_iv michael@0: /** michael@0: * XXX_get_query_object_iv: michael@0: * - depends on XXX_query_objects michael@0: * - provide the followed entry point michael@0: * michael@0: * XXX_occlusion_query: michael@0: * - depends on XXX_get_query_object_iv michael@0: * - provide LOCAL_GL_SAMPLES_PASSED michael@0: */ michael@0: public: michael@0: void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv); michael@0: mSymbols.fGetQueryObjectiv(id, pname, params); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_transform_feedback michael@0: public: michael@0: void fBindBufferBase(GLenum target, GLuint index, GLuint buffer) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBindBufferBase); michael@0: mSymbols.fBindBufferBase(target, index, buffer); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBindBufferRange); michael@0: mSymbols.fBindBufferRange(target, index, buffer, offset, size); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fBeginTransformFeedback(GLenum primitiveMode) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback); michael@0: mSymbols.fBeginTransformFeedback(primitiveMode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fEndTransformFeedback() michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fEndTransformFeedback); michael@0: mSymbols.fEndTransformFeedback(); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings); michael@0: mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying); michael@0: mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGetIntegeri_v(GLenum param, GLuint index, GLint* values) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGetIntegeri_v); michael@0: mSymbols.fGetIntegeri_v(param, index, values); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Package XXX_vertex_array_object michael@0: public: michael@0: void fBindVertexArray(GLuint array) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fBindVertexArray); michael@0: mSymbols.fBindVertexArray(array); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fDeleteVertexArrays(GLsizei n, const GLuint *arrays) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays); michael@0: mSymbols.fDeleteVertexArrays(n, arrays); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: void fGenVertexArrays(GLsizei n, GLuint *arrays) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fGenVertexArrays); michael@0: mSymbols.fGenVertexArrays(n, arrays); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: realGLboolean fIsVertexArray(GLuint array) michael@0: { michael@0: BEFORE_GL_CALL; michael@0: ASSERT_SYMBOL_PRESENT(fIsVertexArray); michael@0: realGLboolean ret = mSymbols.fIsVertexArray(array); michael@0: AFTER_GL_CALL; michael@0: return ret; michael@0: } michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Constructor michael@0: public: michael@0: michael@0: typedef struct gfx::SurfaceCaps SurfaceCaps; michael@0: michael@0: michael@0: protected: michael@0: GLContext(const SurfaceCaps& caps, michael@0: GLContext* sharedContext = nullptr, michael@0: bool isOffscreen = false); michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Destructor michael@0: public: michael@0: virtual ~GLContext(); michael@0: michael@0: michael@0: // ----------------------------------------------------------------------------- michael@0: // Everything that isn't standard GL APIs michael@0: protected: michael@0: typedef class gfx::SharedSurface SharedSurface; michael@0: typedef gfx::SharedSurfaceType SharedSurfaceType; michael@0: typedef gfx::SurfaceFormat SurfaceFormat; michael@0: michael@0: virtual bool MakeCurrentImpl(bool aForce) = 0; michael@0: michael@0: public: michael@0: #ifdef MOZ_ENABLE_GL_TRACKING michael@0: static void StaticInit() { michael@0: PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr); michael@0: } michael@0: #endif michael@0: michael@0: bool MakeCurrent(bool aForce = false) { michael@0: if (IsDestroyed()) { michael@0: return false; michael@0: } michael@0: #ifdef MOZ_ENABLE_GL_TRACKING michael@0: PR_SetThreadPrivate(sCurrentGLContextTLS, this); michael@0: michael@0: // XXX this assertion is disabled because it's triggering on Mac; michael@0: // we need to figure out why and reenable it. michael@0: #if 0 michael@0: // IsOwningThreadCurrent is a bit of a misnomer; michael@0: // the "owning thread" is the creation thread, michael@0: // and the only thread that can own this. We don't michael@0: // support contexts used on multiple threads. michael@0: NS_ASSERTION(IsOwningThreadCurrent(), michael@0: "MakeCurrent() called on different thread than this context was created on!"); michael@0: #endif michael@0: #endif michael@0: return MakeCurrentImpl(aForce); michael@0: } michael@0: michael@0: virtual bool Init() = 0; michael@0: michael@0: virtual bool SetupLookupFunction() = 0; michael@0: michael@0: virtual void ReleaseSurface() {} michael@0: michael@0: // Mark this context as destroyed. This will nullptr out all michael@0: // the GL function pointers! michael@0: void MarkDestroyed(); michael@0: michael@0: bool IsDestroyed() { michael@0: // MarkDestroyed will mark all these as null. michael@0: return mSymbols.fUseProgram == nullptr; michael@0: } michael@0: michael@0: GLContext *GetSharedContext() { return mSharedContext; } michael@0: michael@0: /** michael@0: * Returns true if the thread on which this context was created is the currently michael@0: * executing thread. michael@0: */ michael@0: bool IsOwningThreadCurrent(); michael@0: void DispatchToOwningThread(nsIRunnable *event); michael@0: michael@0: static void PlatformStartup(); michael@0: michael@0: public: michael@0: /** michael@0: * If this context wraps a double-buffered target, swap the back michael@0: * and front buffers. It should be assumed that after a swap, the michael@0: * contents of the new back buffer are undefined. michael@0: */ michael@0: virtual bool SwapBuffers() { return false; } michael@0: michael@0: /** michael@0: * Defines a two-dimensional texture image for context target surface michael@0: */ michael@0: virtual bool BindTexImage() { return false; } michael@0: /* michael@0: * Releases a color buffer that is being used as a texture michael@0: */ michael@0: virtual bool ReleaseTexImage() { return false; } michael@0: michael@0: // Before reads from offscreen texture michael@0: void GuaranteeResolve(); michael@0: michael@0: /* michael@0: * Resize the current offscreen buffer. Returns true on success. michael@0: * If it returns false, the context should be treated as unusable michael@0: * and should be recreated. After the resize, the viewport is not michael@0: * changed; glViewport should be called as appropriate. michael@0: * michael@0: * Only valid if IsOffscreen() returns true. michael@0: */ michael@0: bool ResizeOffscreen(const gfx::IntSize& size) { michael@0: return ResizeScreenBuffer(size); michael@0: } michael@0: michael@0: /* michael@0: * Return size of this offscreen context. michael@0: * michael@0: * Only valid if IsOffscreen() returns true. michael@0: */ michael@0: const gfx::IntSize& OffscreenSize() const; michael@0: michael@0: void BindFB(GLuint fb) { michael@0: fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb); michael@0: MOZ_ASSERT(!fb || fIsFramebuffer(fb)); michael@0: } michael@0: michael@0: void BindDrawFB(GLuint fb) { michael@0: fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb); michael@0: } michael@0: michael@0: void BindReadFB(GLuint fb) { michael@0: fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb); michael@0: } michael@0: michael@0: GLuint GetDrawFB() { michael@0: if (mScreen) michael@0: return mScreen->GetDrawFB(); michael@0: michael@0: GLuint ret = 0; michael@0: GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret); michael@0: return ret; michael@0: } michael@0: michael@0: GLuint GetReadFB() { michael@0: if (mScreen) michael@0: return mScreen->GetReadFB(); michael@0: michael@0: GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit) michael@0: ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT michael@0: : LOCAL_GL_FRAMEBUFFER_BINDING; michael@0: michael@0: GLuint ret = 0; michael@0: GetUIntegerv(bindEnum, &ret); michael@0: return ret; michael@0: } michael@0: michael@0: GLuint GetFB() { michael@0: if (mScreen) { michael@0: // This has a very important extra assert that checks that we're michael@0: // not accidentally ignoring a situation where the draw and read michael@0: // FBs differ. michael@0: return mScreen->GetFB(); michael@0: } michael@0: michael@0: GLuint ret = 0; michael@0: GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret); michael@0: return ret; michael@0: } michael@0: michael@0: private: michael@0: void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { michael@0: switch (precisiontype) { michael@0: case LOCAL_GL_LOW_FLOAT: michael@0: case LOCAL_GL_MEDIUM_FLOAT: michael@0: case LOCAL_GL_HIGH_FLOAT: michael@0: // Assume IEEE 754 precision michael@0: range[0] = 127; michael@0: range[1] = 127; michael@0: *precision = 23; michael@0: break; michael@0: case LOCAL_GL_LOW_INT: michael@0: case LOCAL_GL_MEDIUM_INT: michael@0: case LOCAL_GL_HIGH_INT: michael@0: // Some (most) hardware only supports single-precision floating-point numbers, michael@0: // which can accurately represent integers up to +/-16777216 michael@0: range[0] = 24; michael@0: range[1] = 24; michael@0: *precision = 0; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: public: michael@0: michael@0: void ForceDirtyScreen(); michael@0: void CleanDirtyScreen(); michael@0: michael@0: virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; } michael@0: michael@0: virtual bool RenewSurface() { return false; } michael@0: michael@0: // Shared code for GL extensions and GLX extensions. michael@0: static bool ListHasExtension(const GLubyte *extensions, michael@0: const char *extension); michael@0: michael@0: GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; } michael@0: michael@0: public: michael@0: /** michael@0: * Context reset constants. michael@0: * These are used to determine who is guilty when a context reset michael@0: * happens. michael@0: */ michael@0: enum ContextResetARB { michael@0: CONTEXT_NO_ERROR = 0, michael@0: CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253, michael@0: CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254, michael@0: CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255 michael@0: }; michael@0: michael@0: public: michael@0: std::map mFBOMapping; michael@0: michael@0: enum { michael@0: DebugEnabled = 1 << 0, michael@0: DebugTrace = 1 << 1, michael@0: DebugAbortOnError = 1 << 2 michael@0: }; michael@0: michael@0: static uint32_t sDebugMode; michael@0: michael@0: static uint32_t DebugMode() { michael@0: #ifdef DEBUG michael@0: return sDebugMode; michael@0: #else michael@0: return 0; michael@0: #endif michael@0: } michael@0: michael@0: protected: michael@0: nsRefPtr mSharedContext; michael@0: michael@0: // The thread on which this context was created. michael@0: nsCOMPtr mOwningThread; michael@0: michael@0: GLContextSymbols mSymbols; michael@0: michael@0: #ifdef DEBUG michael@0: // GLDebugMode will check that we don't send call michael@0: // to a GLContext that isn't current on the current michael@0: // thread. michael@0: // Store the current context when binding to thread local michael@0: // storage to support DebugMode on an arbitrary thread. michael@0: static unsigned sCurrentGLContextTLS; michael@0: #endif michael@0: michael@0: ScopedDeletePtr mBlitHelper; michael@0: ScopedDeletePtr mBlitTextureImageHelper; michael@0: ScopedDeletePtr mReadTexImageHelper; michael@0: michael@0: public: michael@0: GLBlitHelper* BlitHelper(); michael@0: GLBlitTextureImageHelper* BlitTextureImageHelper(); michael@0: GLReadTexImageHelper* ReadTexImageHelper(); michael@0: michael@0: // Assumes shares are created by all sharing with the same global context. michael@0: bool SharesWith(const GLContext* other) const { michael@0: MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext); michael@0: MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext); michael@0: MOZ_ASSERT(!this->mSharedContext || michael@0: !other->mSharedContext || michael@0: this->mSharedContext == other->mSharedContext); michael@0: michael@0: const GLContext* thisShared = this->mSharedContext ? this->mSharedContext michael@0: : this; michael@0: const GLContext* otherShared = other->mSharedContext ? other->mSharedContext michael@0: : other; michael@0: michael@0: return thisShared == otherShared; michael@0: } michael@0: michael@0: bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps) { michael@0: if (!CreateScreenBuffer(size, caps)) michael@0: return false; michael@0: michael@0: MakeCurrent(); michael@0: fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0); michael@0: fScissor(0, 0, size.width, size.height); michael@0: fViewport(0, 0, size.width, size.height); michael@0: michael@0: mCaps = mScreen->Caps(); michael@0: if (mCaps.any) michael@0: DetermineCaps(); michael@0: michael@0: UpdateGLFormats(mCaps); michael@0: UpdatePixelFormat(); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: protected: michael@0: // Note that it does -not- clear the resized buffers. michael@0: bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) { michael@0: if (!IsOffscreenSizeAllowed(size)) michael@0: return false; michael@0: michael@0: SurfaceCaps tryCaps = caps; michael@0: if (tryCaps.antialias) { michael@0: // AA path michael@0: if (CreateScreenBufferImpl(size, tryCaps)) michael@0: return true; michael@0: michael@0: NS_WARNING("CreateScreenBuffer failed to initialize an AA context! Falling back to no AA..."); michael@0: tryCaps.antialias = false; michael@0: } michael@0: MOZ_ASSERT(!tryCaps.antialias); michael@0: michael@0: if (CreateScreenBufferImpl(size, tryCaps)) michael@0: return true; michael@0: michael@0: NS_WARNING("CreateScreenBuffer failed to initialize non-AA context!"); michael@0: return false; michael@0: } michael@0: michael@0: bool CreateScreenBufferImpl(const gfx::IntSize& size, michael@0: const SurfaceCaps& caps); michael@0: michael@0: public: michael@0: bool ResizeScreenBuffer(const gfx::IntSize& size); michael@0: michael@0: protected: michael@0: SurfaceCaps mCaps; michael@0: nsAutoPtr mGLFormats; michael@0: nsAutoPtr mPixelFormat; michael@0: michael@0: public: michael@0: void DetermineCaps(); michael@0: const SurfaceCaps& Caps() const { michael@0: return mCaps; michael@0: } michael@0: michael@0: // Only varies based on bpp16 and alpha. michael@0: GLFormats ChooseGLFormats(const SurfaceCaps& caps) const; michael@0: void UpdateGLFormats(const SurfaceCaps& caps) { michael@0: mGLFormats = new GLFormats(ChooseGLFormats(caps)); michael@0: } michael@0: michael@0: const GLFormats& GetGLFormats() const { michael@0: MOZ_ASSERT(mGLFormats); michael@0: return *mGLFormats; michael@0: } michael@0: michael@0: PixelBufferFormat QueryPixelFormat(); michael@0: void UpdatePixelFormat(); michael@0: michael@0: const PixelBufferFormat& GetPixelFormat() const { michael@0: MOZ_ASSERT(mPixelFormat); michael@0: return *mPixelFormat; michael@0: } michael@0: michael@0: bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr); michael@0: michael@0: // Does not check completeness. michael@0: void AttachBuffersToFB(GLuint colorTex, GLuint colorRB, michael@0: GLuint depthRB, GLuint stencilRB, michael@0: GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D); michael@0: michael@0: // Passing null is fine if the value you'd get is 0. michael@0: bool AssembleOffscreenFBs(const GLuint colorMSRB, michael@0: const GLuint depthRB, michael@0: const GLuint stencilRB, michael@0: const GLuint texture, michael@0: GLuint* drawFB, michael@0: GLuint* readFB); michael@0: michael@0: protected: michael@0: friend class GLScreenBuffer; michael@0: GLScreenBuffer* mScreen; michael@0: michael@0: void DestroyScreenBuffer(); michael@0: michael@0: SharedSurface_GL* mLockedSurface; michael@0: michael@0: public: michael@0: void LockSurface(SharedSurface_GL* surf) { michael@0: MOZ_ASSERT(!mLockedSurface); michael@0: mLockedSurface = surf; michael@0: } michael@0: michael@0: void UnlockSurface(SharedSurface_GL* surf) { michael@0: MOZ_ASSERT(mLockedSurface == surf); michael@0: mLockedSurface = nullptr; michael@0: } michael@0: michael@0: SharedSurface_GL* GetLockedSurface() const { michael@0: return mLockedSurface; michael@0: } michael@0: michael@0: bool IsOffscreen() const { michael@0: return mScreen; michael@0: } michael@0: michael@0: GLScreenBuffer* Screen() const { michael@0: return mScreen; michael@0: } michael@0: michael@0: bool PublishFrame(); michael@0: SharedSurface_GL* RequestFrame(); michael@0: michael@0: /* Clear to transparent black, with 0 depth and stencil, michael@0: * while preserving current ClearColor etc. values. michael@0: * Useful for resizing offscreen buffers. michael@0: */ michael@0: void ClearSafely(); michael@0: michael@0: bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; } michael@0: michael@0: protected: michael@0: nsRefPtr mTexGarbageBin; michael@0: michael@0: public: michael@0: TextureGarbageBin* TexGarbageBin() { michael@0: MOZ_ASSERT(mTexGarbageBin); michael@0: return mTexGarbageBin; michael@0: } michael@0: michael@0: void EmptyTexGarbageBin(); michael@0: michael@0: bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const; michael@0: michael@0: protected: michael@0: bool InitWithPrefix(const char *prefix, bool trygl); michael@0: michael@0: void InitExtensions(); michael@0: michael@0: GLint mViewportRect[4]; michael@0: GLint mScissorRect[4]; michael@0: michael@0: GLint mMaxTextureSize; michael@0: GLint mMaxCubeMapTextureSize; michael@0: GLint mMaxTextureImageSize; michael@0: GLint mMaxRenderbufferSize; michael@0: GLsizei mMaxSamples; michael@0: bool mNeedsTextureSizeChecks; michael@0: bool mWorkAroundDriverBugs; michael@0: michael@0: bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const { michael@0: if (mNeedsTextureSizeChecks) { michael@0: // some drivers incorrectly handle some large texture sizes that are below the michael@0: // max texture size that they report. So we check ourselves against our own values michael@0: // (mMax[CubeMap]TextureSize). michael@0: // see bug 737182 for Mac Intel 2D textures michael@0: // see bug 684882 for Mac Intel cube map textures michael@0: // see bug 814716 for Mesa Nouveau michael@0: GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP || michael@0: (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X && michael@0: target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) michael@0: ? mMaxCubeMapTextureSize michael@0: : mMaxTextureSize; michael@0: return width <= maxSize && height <= maxSize; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: michael@0: public: michael@0: michael@0: void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) { michael@0: if (mViewportRect[0] == x && michael@0: mViewportRect[1] == y && michael@0: mViewportRect[2] == width && michael@0: mViewportRect[3] == height) michael@0: { michael@0: return; michael@0: } michael@0: mViewportRect[0] = x; michael@0: mViewportRect[1] = y; michael@0: mViewportRect[2] = width; michael@0: mViewportRect[3] = height; michael@0: BEFORE_GL_CALL; michael@0: mSymbols.fViewport(x, y, width, height); michael@0: AFTER_GL_CALL; michael@0: } michael@0: michael@0: #undef ASSERT_SYMBOL_PRESENT michael@0: michael@0: #ifdef MOZ_ENABLE_GL_TRACKING michael@0: void CreatedProgram(GLContext *aOrigin, GLuint aName); michael@0: void CreatedShader(GLContext *aOrigin, GLuint aName); michael@0: void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames); michael@0: void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames); michael@0: void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames); michael@0: void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames); michael@0: void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames); michael@0: void DeletedProgram(GLContext *aOrigin, GLuint aName); michael@0: void DeletedShader(GLContext *aOrigin, GLuint aName); michael@0: void DeletedBuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames); michael@0: void DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames); michael@0: void DeletedTextures(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames); michael@0: void DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames); michael@0: void DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames); michael@0: michael@0: void SharedContextDestroyed(GLContext *aChild); michael@0: void ReportOutstandingNames(); michael@0: michael@0: struct NamedResource { michael@0: NamedResource() michael@0: : origin(nullptr), name(0), originDeleted(false) michael@0: { } michael@0: michael@0: NamedResource(GLContext *aOrigin, GLuint aName) michael@0: : origin(aOrigin), name(aName), originDeleted(false) michael@0: { } michael@0: michael@0: GLContext *origin; michael@0: GLuint name; michael@0: bool originDeleted; michael@0: michael@0: // for sorting michael@0: bool operator<(const NamedResource& aOther) const { michael@0: if (intptr_t(origin) < intptr_t(aOther.origin)) michael@0: return true; michael@0: if (name < aOther.name) michael@0: return true; michael@0: return false; michael@0: } michael@0: bool operator==(const NamedResource& aOther) const { michael@0: return origin == aOther.origin && michael@0: name == aOther.name && michael@0: originDeleted == aOther.originDeleted; michael@0: } michael@0: }; michael@0: michael@0: nsTArray mTrackedPrograms; michael@0: nsTArray mTrackedShaders; michael@0: nsTArray mTrackedTextures; michael@0: nsTArray mTrackedFramebuffers; michael@0: nsTArray mTrackedRenderbuffers; michael@0: nsTArray mTrackedBuffers; michael@0: nsTArray mTrackedQueries; michael@0: #endif michael@0: }; michael@0: michael@0: bool DoesStringMatch(const char* aString, const char *aWantedString); michael@0: michael@0: michael@0: } /* namespace gl */ michael@0: } /* namespace mozilla */ michael@0: michael@0: #endif /* GLCONTEXT_H_ */