Example #1
0
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;
}
Example #2
0
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) {
Example #6
0
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;
}