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;
}
Esempio n. 2
0
/****** 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;
}
Esempio n. 4
0
/****** 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;
}