GrGLint GLTestContext::createTextureRectangle(int width, int height, GrGLenum internalFormat, GrGLenum externalFormat, GrGLenum externalType, GrGLvoid* data) { if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER(3, 1)) && !fGL->fExtensions.has("GL_ARB_texture_rectangle")) { return 0; } if (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) { return 0; } GrGLuint id; GR_GL_CALL(fGL, GenTextures(1, &id)); GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id)); GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST)); GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST)); GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE)); GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE)); GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width, height, 0, externalFormat, externalType, data)); return id; }
std::unique_ptr<sk_gpu_test::FenceSync> GLFenceSync::MakeIfSupported( const sk_gpu_test::GLTestContext* ctx) { std::unique_ptr<FenceSync> ret; if (kGL_GrGLStandard == ctx->gl()->fStandard) { if (GrGLGetVersion(ctx->gl()) < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync")) { return nullptr; } ret.reset(new GLFenceSync(ctx)); } else { if (ctx->gl()->hasExtension("GL_APPLE_sync")) { ret.reset(new GLFenceSync(ctx, "APPLE")); } else if (ctx->gl()->hasExtension("GL_NV_fence")) { ret.reset(new GLNVFenceSync(ctx)); } else if (GrGLGetVersion(ctx->gl()) >= GR_GL_VER(3, 0)) { ret.reset(new GLFenceSync(ctx)); } else { return nullptr; } } if (!ret->validate()) { ret = nullptr; } return ret; }
bool GrGLInterface::validate(GrGLBinding binding) const { // kNone must be 0 so that the check we're about to do can never succeed if // binding == kNone. GR_STATIC_ASSERT(kNone_GrGLBinding == 0); if (0 == (binding & fBindingsExported)) { return false; } // functions that are always required if (NULL == fActiveTexture || NULL == fAttachShader || NULL == fBindAttribLocation || NULL == fBindBuffer || NULL == fBindTexture || NULL == fBlendFunc || NULL == fBufferData || NULL == fBufferSubData || NULL == fClear || NULL == fClearColor || NULL == fClearStencil || NULL == fColorMask || NULL == fCompileShader || NULL == fCreateProgram || NULL == fCreateShader || NULL == fCullFace || NULL == fDeleteBuffers || NULL == fDeleteProgram || NULL == fDeleteShader || NULL == fDeleteTextures || NULL == fDepthMask || NULL == fDisable || NULL == fDisableVertexAttribArray || NULL == fDrawArrays || NULL == fDrawElements || NULL == fEnable || NULL == fEnableVertexAttribArray || NULL == fFrontFace || NULL == fGenBuffers || NULL == fGenTextures || NULL == fGetBufferParameteriv || NULL == fGetError || NULL == fGetIntegerv || NULL == fGetProgramInfoLog || NULL == fGetProgramiv || NULL == fGetShaderInfoLog || NULL == fGetShaderiv || NULL == fGetString || NULL == fGetUniformLocation || NULL == fLinkProgram || NULL == fPixelStorei || NULL == fReadPixels || NULL == fScissor || NULL == fShaderSource || NULL == fStencilFunc || NULL == fStencilMask || NULL == fStencilOp || NULL == fTexImage2D || NULL == fTexParameteri || NULL == fTexSubImage2D || NULL == fUniform1f || NULL == fUniform1i || NULL == fUniform1fv || NULL == fUniform1iv || NULL == fUniform2f || NULL == fUniform2i || NULL == fUniform2fv || NULL == fUniform2iv || NULL == fUniform3f || NULL == fUniform3i || NULL == fUniform3fv || NULL == fUniform3iv || NULL == fUniform4f || NULL == fUniform4i || NULL == fUniform4fv || NULL == fUniform4iv || NULL == fUniformMatrix2fv || NULL == fUniformMatrix3fv || NULL == fUniformMatrix4fv || NULL == fUseProgram || NULL == fVertexAttrib4fv || NULL == fVertexAttribPointer || NULL == fViewport || NULL == fBindFramebuffer || NULL == fBindRenderbuffer || NULL == fCheckFramebufferStatus || NULL == fDeleteFramebuffers || NULL == fDeleteRenderbuffers || NULL == fFinish || NULL == fFlush || NULL == fFramebufferRenderbuffer || NULL == fFramebufferTexture2D || NULL == fGetFramebufferAttachmentParameteriv || NULL == fGetRenderbufferParameteriv || NULL == fGenFramebuffers || NULL == fGenRenderbuffers || NULL == fRenderbufferStorage) { return false; } const char* ext; GrGLVersion glVer = GrGLGetVersion(this); ext = (const char*)fGetString(GR_GL_EXTENSIONS); // Now check that baseline ES/Desktop fns not covered above are present // and that we have fn pointers for any advertised extensions that we will // try to use. // these functions are part of ES2, we assume they are available // On the desktop we assume they are available if the extension // is present or GL version is high enough. if (kES2_GrGLBinding == binding) { if (NULL == fBlendColor || NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } else if (kDesktop_GrGLBinding == binding) { if (glVer >= GR_GL_VER(2,0)) { if (NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { return false; } if (glVer >= GR_GL_VER(2,0) || GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) { if (NULL == fDrawBuffers) { return false; } } if (glVer >= GR_GL_VER(1,4) || GrGLHasExtensionFromString("GL_EXT_blend_color", ext)) { if (NULL == fBlendColor) { return false; } } if (glVer >= GR_GL_VER(1,5) || GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) { if (NULL == fGenQueries || NULL == fDeleteQueries || NULL == fBeginQuery || NULL == fEndQuery || NULL == fGetQueryiv || NULL == fGetQueryObjectiv || NULL == fGetQueryObjectuiv) { return false; } } if (glVer >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", ext) || GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) { if (NULL == fGetQueryObjecti64v || NULL == fGetQueryObjectui64v) { return false; } } if (glVer >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) { if (NULL == fQueryCounter) { return false; } } } // optional function on desktop before 1.3 if (kDesktop_GrGLBinding != binding || (glVer >= GR_GL_VER(1,3) || GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) { if (NULL == fCompressedTexImage2D) { return false; } } // part of desktop GL, but not ES if (kDesktop_GrGLBinding == binding && (NULL == fLineWidth || NULL == fGetTexLevelParameteriv || NULL == fDrawBuffer || NULL == fReadBuffer)) { return false; } // GL_EXT_texture_storage is part of desktop 4.2 // There is a desktop ARB extension and an ES+desktop EXT extension if (kDesktop_GrGLBinding == binding) { if (glVer >= GR_GL_VER(4,2) || GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) || GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) { if (NULL == fTexStorage2D) { return false; } } } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) { if (NULL == fTexStorage2D) { return false; } } // FBO MSAA if (kDesktop_GrGLBinding == binding) { // GL 3.0 and the ARB extension have multisample + blit if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } else { if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) && NULL == fBlitFramebuffer) { return false; } if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) && NULL == fRenderbufferStorageMultisample) { return false; } } } else { if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fResolveMultisampleFramebuffer) { return false; } } } // On ES buffer mapping is an extension. On Desktop // buffer mapping was part of original VBO extension // which we require. if (kDesktop_GrGLBinding == binding || GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) { if (NULL == fMapBuffer || NULL == fUnmapBuffer) { return false; } } // Dual source blending if (kDesktop_GrGLBinding == binding && (glVer >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) { if (NULL == fBindFragDataLocationIndexed) { return false; } } return true; }
bool GrGLInterface::validate(GrEngine engine) const { bool isDesktop = this->supportsDesktop(); bool isES = this->supportsES(); if (isDesktop == isES) { // must have one, don't support both in same interface return false; } // functions that are always required if (NULL == fActiveTexture || NULL == fBindBuffer || NULL == fBindTexture || NULL == fBlendFunc || NULL == fBufferData || NULL == fBufferSubData || NULL == fClear || NULL == fClearColor || NULL == fClearStencil || NULL == fColorMask || NULL == fCullFace || NULL == fDeleteBuffers || NULL == fDeleteTextures || NULL == fDepthMask || NULL == fDisable || NULL == fDrawArrays || NULL == fDrawElements || NULL == fEnable || NULL == fFrontFace || NULL == fGenBuffers || NULL == fGenTextures || NULL == fGetBufferParameteriv || NULL == fGetError || NULL == fGetIntegerv || NULL == fGetString || NULL == fPixelStorei || NULL == fReadPixels || NULL == fScissor || NULL == fStencilFunc || NULL == fStencilMask || NULL == fStencilOp || NULL == fTexImage2D || NULL == fTexParameteri || NULL == fTexSubImage2D || NULL == fViewport || NULL == fBindFramebuffer || NULL == fBindRenderbuffer || NULL == fCheckFramebufferStatus || NULL == fDeleteFramebuffers || NULL == fDeleteRenderbuffers || NULL == fFramebufferRenderbuffer || NULL == fFramebufferTexture2D || NULL == fGetFramebufferAttachmentParameteriv || NULL == fGetRenderbufferParameteriv || NULL == fGenFramebuffers || NULL == fGenRenderbuffers || NULL == fRenderbufferStorage) { return false; } switch (engine) { case kOpenGL_Shaders_GrEngine: if (kES1_GrGLBinding == fBindingsExported) { return false; } if (!this->validateShaderFunctions()) { return false; } break; case kOpenGL_Fixed_GrEngine: if (kES1_GrGLBinding == fBindingsExported) { return false; } if (!this->validateFixedFunctions()) { return false; } break; default: return false; } const char* ext; GrGLVersion glVer = GrGLGetVersion(this); ext = (const char*)fGetString(GR_GL_EXTENSIONS); // Now check that baseline ES/Desktop fns not covered above are present // and that we have fn pointers for any advertised extensions that we will // try to use. // these functions are part of ES2, we assume they are available // On the desktop we assume they are available if the extension // is present or GL version is high enough. if ((kES2_GrGLBinding & fBindingsExported)) { if (NULL == fBlendColor || NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } else if (kDesktop_GrGLBinding == fBindingsExported) { if (glVer >= GR_GL_VER(2,0)) { if (NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { return false; } if (glVer >= GR_GL_VER(2,0) || GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) { if (NULL == fDrawBuffers) { return false; } } if (glVer >= GR_GL_VER(1,4) || GrGLHasExtensionFromString("GL_EXT_blend_color", ext)) { if (NULL == fBlendColor) { return false; } } } // optional function on desktop before 1.3 if (kDesktop_GrGLBinding != fBindingsExported || (glVer >= GR_GL_VER(1,3) || GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) { if (NULL == fCompressedTexImage2D) { return false; } } // part of desktop GL, but not ES if (kDesktop_GrGLBinding == fBindingsExported && (NULL == fLineWidth || NULL == fGetTexLevelParameteriv || NULL == fDrawBuffer || NULL == fReadBuffer)) { return false; } // FBO MSAA if (kDesktop_GrGLBinding == fBindingsExported) { // GL 3.0 and the ARB extension have multisample + blit if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } else { if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) && NULL == fBlitFramebuffer) { return false; } if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) && NULL == fRenderbufferStorageMultisample) { return false; } } } else { if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) { if (NULL == fRenderbufferStorageMultisample || NULL == fResolveMultisampleFramebuffer) { return false; } } } // On ES buffer mapping is an extension. On Desktop // buffer mapping was part of original VBO extension // which we require. if (kDesktop_GrGLBinding == fBindingsExported || GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) { if (NULL == fMapBuffer || NULL == fUnmapBuffer) { return false; } } // Dual source blending if (kDesktop_GrGLBinding == fBindingsExported && (glVer >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) { if (NULL == fBindFragDataLocationIndexed) { return false; } } return true; }
bool GrGLInterface::validate() const { if (kNone_GrGLStandard == fStandard) { RETURN_FALSE_INTERFACE } if (!fExtensions.isInitialized()) { RETURN_FALSE_INTERFACE } // functions that are always required if (nullptr == fFunctions.fActiveTexture || nullptr == fFunctions.fAttachShader || nullptr == fFunctions.fBindAttribLocation || nullptr == fFunctions.fBindBuffer || nullptr == fFunctions.fBindTexture || nullptr == fFunctions.fBlendColor || // -> GL >= 1.4 or extension, ES >= 2.0 nullptr == fFunctions.fBlendEquation || // -> GL >= 1.4 or extension, ES >= 2.0 nullptr == fFunctions.fBlendFunc || nullptr == fFunctions.fBufferData || nullptr == fFunctions.fBufferSubData || nullptr == fFunctions.fClear || nullptr == fFunctions.fClearColor || nullptr == fFunctions.fClearStencil || nullptr == fFunctions.fColorMask || nullptr == fFunctions.fCompileShader || nullptr == fFunctions.fCopyTexSubImage2D || nullptr == fFunctions.fCreateProgram || nullptr == fFunctions.fCreateShader || nullptr == fFunctions.fCullFace || nullptr == fFunctions.fDeleteBuffers || nullptr == fFunctions.fDeleteProgram || nullptr == fFunctions.fDeleteShader || nullptr == fFunctions.fDeleteTextures || nullptr == fFunctions.fDepthMask || nullptr == fFunctions.fDisable || nullptr == fFunctions.fDisableVertexAttribArray || nullptr == fFunctions.fDrawArrays || nullptr == fFunctions.fDrawElements || nullptr == fFunctions.fEnable || nullptr == fFunctions.fEnableVertexAttribArray || nullptr == fFunctions.fFrontFace || nullptr == fFunctions.fGenBuffers || nullptr == fFunctions.fGenTextures || nullptr == fFunctions.fGetBufferParameteriv || nullptr == fFunctions.fGenerateMipmap || nullptr == fFunctions.fGetError || nullptr == fFunctions.fGetIntegerv || nullptr == fFunctions.fGetProgramInfoLog || nullptr == fFunctions.fGetProgramiv || nullptr == fFunctions.fGetShaderInfoLog || nullptr == fFunctions.fGetShaderiv || nullptr == fFunctions.fGetString || nullptr == fFunctions.fGetUniformLocation || #if 0 // Not included in Chrome yet nullptr == fFunctions.fIsTexture || #endif nullptr == fFunctions.fLinkProgram || nullptr == fFunctions.fLineWidth || nullptr == fFunctions.fPixelStorei || nullptr == fFunctions.fReadPixels || nullptr == fFunctions.fScissor || nullptr == fFunctions.fShaderSource || nullptr == fFunctions.fStencilFunc || nullptr == fFunctions.fStencilMask || nullptr == fFunctions.fStencilOp || nullptr == fFunctions.fTexImage2D || nullptr == fFunctions.fTexParameteri || nullptr == fFunctions.fTexParameteriv || nullptr == fFunctions.fTexSubImage2D || nullptr == fFunctions.fUniform1f || nullptr == fFunctions.fUniform1i || nullptr == fFunctions.fUniform1fv || nullptr == fFunctions.fUniform1iv || nullptr == fFunctions.fUniform2f || nullptr == fFunctions.fUniform2i || nullptr == fFunctions.fUniform2fv || nullptr == fFunctions.fUniform2iv || nullptr == fFunctions.fUniform3f || nullptr == fFunctions.fUniform3i || nullptr == fFunctions.fUniform3fv || nullptr == fFunctions.fUniform3iv || nullptr == fFunctions.fUniform4f || nullptr == fFunctions.fUniform4i || nullptr == fFunctions.fUniform4fv || nullptr == fFunctions.fUniform4iv || nullptr == fFunctions.fUniformMatrix2fv || nullptr == fFunctions.fUniformMatrix3fv || nullptr == fFunctions.fUniformMatrix4fv || nullptr == fFunctions.fUseProgram || nullptr == fFunctions.fVertexAttrib1f || nullptr == fFunctions.fVertexAttrib2fv || nullptr == fFunctions.fVertexAttrib3fv || nullptr == fFunctions.fVertexAttrib4fv || nullptr == fFunctions.fVertexAttribPointer || nullptr == fFunctions.fViewport || nullptr == fFunctions.fBindFramebuffer || nullptr == fFunctions.fBindRenderbuffer || nullptr == fFunctions.fCheckFramebufferStatus || nullptr == fFunctions.fDeleteFramebuffers || nullptr == fFunctions.fDeleteRenderbuffers || nullptr == fFunctions.fFinish || nullptr == fFunctions.fFlush || nullptr == fFunctions.fFramebufferRenderbuffer || nullptr == fFunctions.fFramebufferTexture2D || nullptr == fFunctions.fGetFramebufferAttachmentParameteriv || nullptr == fFunctions.fGetRenderbufferParameteriv || nullptr == fFunctions.fGenFramebuffers || nullptr == fFunctions.fGenRenderbuffers || nullptr == fFunctions.fRenderbufferStorage) { RETURN_FALSE_INTERFACE } GrGLVersion glVer = GrGLGetVersion(this); if (GR_GL_INVALID_VER == glVer) { RETURN_FALSE_INTERFACE } // Now check that baseline ES/Desktop fns not covered above are present // and that we have fn pointers for any advertised fExtensions that we will // try to use. // these functions are part of ES2, we assume they are available // On the desktop we assume they are available if the extension // is present or GL version is high enough. if (kGLES_GrGLStandard == fStandard) { if (nullptr == fFunctions.fStencilFuncSeparate || nullptr == fFunctions.fStencilMaskSeparate || nullptr == fFunctions.fStencilOpSeparate) { RETURN_FALSE_INTERFACE } } else if (kGL_GrGLStandard == fStandard) {
bool GrGLInterface::validate(GrGLBinding binding) const { // kNone must be 0 so that the check we're about to do can never succeed if // binding == kNone. GR_STATIC_ASSERT(kNone_GrGLBinding == 0); if (0 == (binding & fBindingsExported)) { return false; } GrGLExtensions extensions; if (!extensions.init(binding, this)) { return false; } // functions that are always required if (NULL == fActiveTexture || NULL == fAttachShader || NULL == fBindAttribLocation || NULL == fBindBuffer || NULL == fBindTexture || NULL == fBlendFunc || NULL == fBlendColor || // -> GL >= 1.4, ES >= 2.0 or extension NULL == fBufferData || NULL == fBufferSubData || NULL == fClear || NULL == fClearColor || NULL == fClearStencil || NULL == fColorMask || NULL == fCompileShader || NULL == fCopyTexSubImage2D || NULL == fCreateProgram || NULL == fCreateShader || NULL == fCullFace || NULL == fDeleteBuffers || NULL == fDeleteProgram || NULL == fDeleteShader || NULL == fDeleteTextures || NULL == fDepthMask || NULL == fDisable || NULL == fDisableVertexAttribArray || NULL == fDrawArrays || NULL == fDrawElements || NULL == fEnable || NULL == fEnableVertexAttribArray || NULL == fFrontFace || NULL == fGenBuffers || NULL == fGenTextures || NULL == fGetBufferParameteriv || NULL == fGetError || NULL == fGetIntegerv || NULL == fGetProgramInfoLog || NULL == fGetProgramiv || NULL == fGetShaderInfoLog || NULL == fGetShaderiv || NULL == fGetString || NULL == fGetUniformLocation || NULL == fLinkProgram || NULL == fPixelStorei || NULL == fReadPixels || NULL == fScissor || NULL == fShaderSource || NULL == fStencilFunc || NULL == fStencilMask || NULL == fStencilOp || NULL == fTexImage2D || NULL == fTexParameteri || NULL == fTexParameteriv || NULL == fTexSubImage2D || NULL == fUniform1f || NULL == fUniform1i || NULL == fUniform1fv || NULL == fUniform1iv || NULL == fUniform2f || NULL == fUniform2i || NULL == fUniform2fv || NULL == fUniform2iv || NULL == fUniform3f || NULL == fUniform3i || NULL == fUniform3fv || NULL == fUniform3iv || NULL == fUniform4f || NULL == fUniform4i || NULL == fUniform4fv || NULL == fUniform4iv || NULL == fUniformMatrix2fv || NULL == fUniformMatrix3fv || NULL == fUniformMatrix4fv || NULL == fUseProgram || NULL == fVertexAttrib4fv || NULL == fVertexAttribPointer || NULL == fViewport || NULL == fBindFramebuffer || NULL == fBindRenderbuffer || NULL == fCheckFramebufferStatus || NULL == fDeleteFramebuffers || NULL == fDeleteRenderbuffers || NULL == fFinish || NULL == fFlush || NULL == fFramebufferRenderbuffer || NULL == fFramebufferTexture2D || NULL == fGetFramebufferAttachmentParameteriv || NULL == fGetRenderbufferParameteriv || NULL == fGenFramebuffers || NULL == fGenRenderbuffers || NULL == fRenderbufferStorage) { return false; } GrGLVersion glVer = GrGLGetVersion(this); // Now check that baseline ES/Desktop fns not covered above are present // and that we have fn pointers for any advertised extensions that we will // try to use. // these functions are part of ES2, we assume they are available // On the desktop we assume they are available if the extension // is present or GL version is high enough. if (kES2_GrGLBinding == binding) { if (NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } else if (kDesktop_GrGLBinding == binding) { if (glVer >= GR_GL_VER(2,0)) { if (NULL == fStencilFuncSeparate || NULL == fStencilMaskSeparate || NULL == fStencilOpSeparate) { return false; } } if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) { return false; } if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) { if (NULL == fDrawBuffers) { return false; } } if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query")) { if (NULL == fGenQueries || NULL == fDeleteQueries || NULL == fBeginQuery || NULL == fEndQuery || NULL == fGetQueryiv || NULL == fGetQueryObjectiv || NULL == fGetQueryObjectuiv) { return false; } } if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query") || extensions.has("GL_EXT_timer_query")) { if (NULL == fGetQueryObjecti64v || NULL == fGetQueryObjectui64v) { return false; } } if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { if (NULL == fQueryCounter) { return false; } } // The below two blocks are checks for functions used with // GL_NV_path_rendering. We're not enforcing that they be non-NULL // because they aren't actually called at this time. if (false && (NULL == fMatrixMode || NULL == fLoadIdentity || NULL == fLoadMatrixf)) { return false; } if (false && extensions.has("GL_NV_path_rendering")) { if (NULL == fPathCommands || NULL == fPathCoords || NULL == fPathSubCommands || NULL == fPathSubCoords || NULL == fPathString || NULL == fPathGlyphs || NULL == fPathGlyphRange || NULL == fWeightPaths || NULL == fCopyPath || NULL == fInterpolatePaths || NULL == fTransformPath || NULL == fPathParameteriv || NULL == fPathParameteri || NULL == fPathParameterfv || NULL == fPathParameterf || NULL == fPathDashArray || NULL == fGenPaths || NULL == fDeletePaths || NULL == fIsPath || NULL == fPathStencilFunc || NULL == fPathStencilDepthOffset || NULL == fStencilFillPath || NULL == fStencilStrokePath || NULL == fStencilFillPathInstanced || NULL == fStencilStrokePathInstanced || NULL == fPathCoverDepthFunc || NULL == fPathColorGen || NULL == fPathTexGen || NULL == fPathFogGen || NULL == fCoverFillPath || NULL == fCoverStrokePath || NULL == fCoverFillPathInstanced || NULL == fCoverStrokePathInstanced || NULL == fGetPathParameteriv || NULL == fGetPathParameterfv || NULL == fGetPathCommands || NULL == fGetPathCoords || NULL == fGetPathDashArray || NULL == fGetPathMetrics || NULL == fGetPathMetricRange || NULL == fGetPathSpacing || NULL == fGetPathColorGeniv || NULL == fGetPathColorGenfv || NULL == fGetPathTexGeniv || NULL == fGetPathTexGenfv || NULL == fIsPointInFillPath || NULL == fIsPointInStrokePath || NULL == fGetPathLength || NULL == fPointAlongPath) { return false; } } } // optional function on desktop before 1.3 if (kDesktop_GrGLBinding != binding || (glVer >= GR_GL_VER(1,3)) || extensions.has("GL_ARB_texture_compression")) { if (NULL == fCompressedTexImage2D) { return false; } } // part of desktop GL, but not ES if (kDesktop_GrGLBinding == binding && (NULL == fLineWidth || NULL == fGetTexLevelParameteriv || NULL == fDrawBuffer || NULL == fReadBuffer)) { return false; } // GL_EXT_texture_storage is part of desktop 4.2 // There is a desktop ARB extension and an ES+desktop EXT extension if (kDesktop_GrGLBinding == binding) { if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage") || extensions.has("GL_EXT_texture_storage")) { if (NULL == fTexStorage2D) { return false; } } } else if (extensions.has("GL_EXT_texture_storage")) { if (NULL == fTexStorage2D) { return false; } } if (extensions.has("GL_EXT_discard_framebuffer")) { // FIXME: Remove this once Chromium is updated to provide this function #if 0 if (NULL == fDiscardFramebuffer) { return false; } #endif } // FBO MSAA if (kDesktop_GrGLBinding == binding) { // GL 3.0 and the ARB extension have multisample + blit if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } else { if (extensions.has("GL_EXT_framebuffer_blit") && NULL == fBlitFramebuffer) { return false; } if (extensions.has("GL_EXT_framebuffer_multisample") && NULL == fRenderbufferStorageMultisample) { return false; } } } else { if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) { if (NULL == fRenderbufferStorageMultisample || NULL == fBlitFramebuffer) { return false; } } if (extensions.has("GL_APPLE_framebuffer_multisample")) { if (NULL == fRenderbufferStorageMultisample || NULL == fResolveMultisampleFramebuffer) { return false; } } if (extensions.has("GL_IMG_multisampled_render_to_texture")) { if (NULL == fRenderbufferStorageMultisample || NULL == fFramebufferTexture2DMultisample) { return false; } } } // On ES buffer mapping is an extension. On Desktop // buffer mapping was part of original VBO extension // which we require. if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) { if (NULL == fMapBuffer || NULL == fUnmapBuffer) { return false; } } // Dual source blending if (kDesktop_GrGLBinding == binding && (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended"))) { if (NULL == fBindFragDataLocationIndexed) { return false; } } if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3, 0)) { if (NULL == fGetStringi) { return false; } } if (kDesktop_GrGLBinding == binding) { if (glVer >= GR_GL_VER(3, 0) || extensions.has("GL_ARB_vertex_array_object")) { if (NULL == fBindVertexArray || NULL == fDeleteVertexArrays || NULL == fGenVertexArrays) { return false; } } } else { if (extensions.has("GL_OES_vertex_array_object")) { if (NULL == fBindVertexArray || NULL == fDeleteVertexArrays || NULL == fGenVertexArrays) { return false; } } } return true; }