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; }
/****** cull/dump_scan/lUndumpList() ****************************************** * NAME * lUndumpList() -- Reads a by lDumpList dumped dump * * SYNOPSIS * lList* lUndumpList(FILE *fp, const char *name, const lDescr *dp) * * FUNCTION * Reads a by lDumpList dumped dump into the memory. * * INPUTS * FILE *fp - file pointer * const char *name - new name of list or NULL if the old name in the * dumpfile should be used as listname * const lDescr *dp - new list descriptor or NULL if the old list * descriptor should be used as list descriptor * * RESULT * lList* - Read list * * NOTES * Actually a type/name matching is only performed for the list * itself and not for its sublists. * If an implementation of changed sublist descriptors is desired * we can probably use the following syntax for lUndumpList. * lList* lUndumpList(fp, name, formatstring, ...) * with formatstring like "%T(%I -> %T(%I->%T))" and the varargs * list: ".....", lDescr1, fieldname1, lDescr2, fieldname2, lDescr3 * or write a wrapper around lUndumpList which parses this format and * hands over the varargs list to lUndumpList ******************************************************************************/ lList *lUndumpList(FILE *fp, const char *name, const lDescr *dp) { lList *lp = NULL; lListElem *fep, *ep; lDescr *fdp = NULL; int i, j, nelem, n, k; int *found; char *oldname; DENTER(CULL_LAYER, "lUndumpList"); if (!fp) { LERROR(LEFILENULL); DRETURN(NULL); } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); DRETURN(NULL); } /* read listname */ if (fGetString(fp, &oldname)) { printf("fGetString failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read number of elems */ if (fGetInt(fp, &nelem)) { printf("fGetInt failed\n"); LERROR(LEFIELDREAD); DRETURN(NULL); } /* read Descriptor from file */ if (!(fdp = lUndumpDescr(fp))) { LERROR(LEFGETDESCR); DRETURN(NULL); } if (!dp) /* dp is NULL, use lDescr from dumpfile */ dp = fdp; /* use old name (from file) if name is NULL */ if (!(lp = lCreateList((name) ? name : oldname, dp))) { FREE(fdp); LERROR(LECREATELIST); DRETURN(NULL); } free(oldname); /* fGetString strdup's */ if ((n = lCountDescr(dp)) <= 0) { LERROR(LECOUNTDESCR); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } if (!(found = (int *) malloc(sizeof(int) * n))) { LERROR(LEMALLOC); FREE(fdp); lFreeList(&lp); DRETURN(NULL); } /* Initialize found array */ for (i = 0; i < n; i++) found[i] = -1; /* Here warnings are displayed if there are additional or missing fields */ for (j = 0; fdp[j].nm != NoName; j++) { for (i = 0; i < n; i++) { if (dp[i].nm == fdp[j].nm && dp[i].mt == fdp[j].mt) { if (found[i] != -1) DPRINTF(("lUndumpList: field %s found twice\n", lNm2Str(dp[i].nm))); found[i] = j; break; } } if (i == n) DPRINTF(("lUndumpList: field %s not needed\n", lNm2Str(fdp[j].nm))); } for (i = 0; i < n; i++) if (found[i] == -1) DPRINTF(("lUndumpList: field %s not found\n", lNm2Str(dp[i].nm))); /* LOOP OVER THE LIST ELEMENTS */ for (k = 0; k < nelem; k++) { if (!(fep = lUndumpElemFp(fp, fdp))) { LERROR(LEUNDUMPELEM); lFreeList(&lp); FREE(found); FREE(fdp); DRETURN(NULL); } if (!(ep = lCreateElem(dp))) { lFreeList(&lp); FREE(found); FREE(fdp); LERROR(LECREATEELEM); DRETURN(NULL); } for (i = 0; i < n; i++) { if (found[i] == -1) { continue; } else if (lCopySwitchPack(fep, ep, found[i], i, true, NULL, NULL) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LECOPYSWITCH); DRETURN(NULL); } } lFreeElem(&fep); if (lAppendElem(lp, ep) == -1) { lFreeList(&lp); lFreeElem(&ep); FREE(found); FREE(fdp); LERROR(LEAPPENDELEM); DRETURN(NULL); } } /* read ket */ if (fGetKet(fp)) { lFreeList(&lp); printf("ket is missing\n"); LERROR(LESYNTAX); } FREE(found); FREE(fdp); DRETURN(lp); }
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; }
/****** cull/dump_scan/lUndumpElemFp() ****************************************** * NAME * lUndumpElemFp() -- Read element from FILE stream * * SYNOPSIS * lListElem* lUndumpElemFp(FILE *fp, const lDescr *dp) * * FUNCTION * Read element from FILE stream * * INPUTS * FILE *fp - file stream * const lDescr *dp - descriptor * * RESULT * lListElem* - Read element ******************************************************************************/ lListElem *lUndumpElemFp(FILE *fp, const lDescr *dp) { lListElem *ep; int n, i; int ret = 0; char *str; u_long32 dummy; DENTER(CULL_LAYER, "lUndumpElemFp"); if (!fp) { LERROR(LEFILENULL); DEXIT; return NULL; } if (!dp) { LERROR(LEDESCRNULL); DEXIT; return NULL; } if (!(ep = lCreateElem(dp))) { LERROR(LECREATEELEM); DEXIT; return NULL; } if ((n = lCountDescr(dp)) <= 0) { LERROR(LECOUNTDESCR); lFreeElem(&ep); DEXIT; return NULL; } /* read bra */ if (fGetBra(fp)) { printf("bra is missing\n"); LERROR(LESYNTAX); lFreeElem(&ep); DEXIT; return NULL; } for (i = 0; i < n && ret == 0; i++) { switch (mt_get_type(dp[i].mt)) { case lIntT: ret = fGetInt(fp, &(ep->cont[i].i)); break; case lUlongT: ret = fGetUlong(fp, &(ep->cont[i].ul)); break; case lStringT: ret = fGetString(fp, &str); if (ret == 0) { lSetPosString(ep, i, str); free(str); /* fGetString strdup's */ } break; case lHostT: ret = fGetHost(fp, &str); if (ret == 0) { lSetPosHost(ep, i, str); free(str); /* fGetHost strdup's */ } break; case lFloatT: ret = fGetFloat(fp, &(ep->cont[i].fl)); break; case lDoubleT: ret = fGetDouble(fp, &(ep->cont[i].db)); break; case lLongT: ret = fGetLong(fp, &(ep->cont[i].l)); break; case lCharT: ret = fGetChar(fp, &(ep->cont[i].c)); break; case lBoolT: ret = fGetBool(fp, &(ep->cont[i].b)); break; case lRefT: /* we will not undump references! But we have to skip the line! */ ret = fGetUlong(fp, &dummy); ep->cont[i].ref = NULL; break; case lObjectT: ret = fGetObject(fp, &(ep->cont[i].obj)); break; case lListT: ret = fGetList(fp, &(ep->cont[i].glp)); break; default: lFreeElem(&ep); unknownType("lUndumpElemFp"); } } /* error handling for loop */ if (ret != 0) { lFreeElem(&ep); LERROR(LEFIELDREAD); DEXIT; return NULL; } /* read ket */ if (fGetKet(fp)) { lFreeElem(&ep); printf("ket is missing\n"); LERROR(LESYNTAX); DEXIT; return NULL; } DEXIT; return ep; }