示例#1
0
/**
 * Set/replace shader source code.  A helper function used by
 * glShaderSource[ARB] and glCreateShaderProgramEXT.
 */
static void
shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source)
{
   struct gl_shader *sh;

   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
   if (!sh)
      return;

   /* free old shader source string and install new one */
   free((void *)sh->Source);
   sh->Source = source;
   sh->CompileStatus = GL_FALSE;
#ifdef DEBUG
   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
#endif
}
示例#2
0
文件: shaderapi.c 项目: UIKit0/mesa
/**
 * Called via glShaderSource() and glShaderSourceARB() API functions.
 * Basically, concatenate the source code strings into one long string
 * and pass it to _mesa_shader_source().
 */
void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
                      const GLcharARB ** string, const GLint * length)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint *offsets;
   GLsizei i, totalLength;
   GLcharARB *source;
   GLuint checksum;

   if (!shaderObj || string == NULL) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
      return;
   }

   /*
    * This array holds offsets of where the appropriate string ends, thus the
    * last element will be set to the total length of the source code.
    */
   offsets = (GLint *) malloc(count * sizeof(GLint));
   if (offsets == NULL) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      if (string[i] == NULL) {
         free((GLvoid *) offsets);
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glShaderSourceARB(null string)");
         return;
      }
      if (length == NULL || length[i] < 0)
         offsets[i] = strlen(string[i]);
      else
         offsets[i] = length[i];
      /* accumulate string lengths */
      if (i > 0)
         offsets[i] += offsets[i - 1];
   }

   /* Total length of source string is sum off all strings plus two.
    * One extra byte for terminating zero, another extra byte to silence
    * valgrind warnings in the parser/grammer code.
    */
   totalLength = offsets[count - 1] + 2;
   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
   if (source == NULL) {
      free((GLvoid *) offsets);
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
      return;
   }

   for (i = 0; i < count; i++) {
      GLint start = (i > 0) ? offsets[i - 1] : 0;
      memcpy(source + start, string[i],
             (offsets[i] - start) * sizeof(GLcharARB));
   }
   source[totalLength - 1] = '\0';
   source[totalLength - 2] = '\0';

   if (SHADER_SUBST) {
      /* Compute the shader's source code checksum then try to open a file
       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
       * original shader source code.  For debugging.
       */
      char filename[100];
      GLcharARB *newSource;

      checksum = _mesa_str_checksum(source);

      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);

      newSource = read_shader(filename);
      if (newSource) {
         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
                       shaderObj, checksum, filename);
         free(source);
         source = newSource;
      }
   }

   shader_source(ctx, shaderObj, source);

   if (SHADER_SUBST) {
      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
      if (sh)
         sh->SourceChecksum = checksum; /* save original checksum */
   }

   free(offsets);
}