Example #1
0
void GLCpuPosInstancedArraysBench::setupSingleVbo(const GrGLInterface* gl,
                                                  const SkMatrix* viewMatrices) {
    // Constants for our various shader programs
    Vertex vertices[kVerticesPerTri * kNumTri];
    for (uint32_t i = 0; i < kNumTri; i++) {
        Vertex* v = &vertices[i * kVerticesPerTri];
        v[0].fPositions.set(-1.0f, -1.0f);
        v[1].fPositions.set( 1.0f, -1.0f);
        v[2].fPositions.set( 1.0f,  1.0f);

        SkPoint* position = reinterpret_cast<SkPoint*>(v);
        viewMatrices[i].mapPointsWithStride(position, sizeof(Vertex), kVerticesPerTri);

        // set colors
        float color = i == kNumTri - 1 ? 1.0f : 0.0f;
        for (uint32_t j = 0; j < kVerticesPerTri; j++) {
            uint32_t offset = 0;
            v->fColors[offset++] = color; v->fColors[offset++] = 0.0f; v->fColors[offset++] = 0.0f;
            v++;
        }
    }

    GrGLuint vbo;
    // setup VBO
    GR_GL_CALL(gl, GenBuffers(1, &vbo));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, vbo));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)(sizeof(SkPoint))));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(vertices), vertices, GR_GL_STATIC_DRAW));
    fBuffers.push_back(vbo);
}
Example #2
0
void GrGpuGLShaders::onResetContext() {
    INHERITED::onResetContext();

    fHWGeometryState.fVertexOffset = ~0;

    // Third party GL code may have left vertex attributes enabled. Some GL
    // implementations (osmesa) may read vetex attributes that are not required
    // by the current shader. Therefore, we have to ensure that only the
    // attributes we require for the current draw are enabled or we may cause an
    // invalid read.

    // Disable all vertex layout bits so that next flush will assume all
    // optional vertex attributes are disabled.
    fHWGeometryState.fVertexLayout = 0;

    // We always use the this attribute and assume it is always enabled.
    int posAttrIdx = GrGLProgram::PositionAttributeIdx();
    GL_CALL(EnableVertexAttribArray(posAttrIdx));
    // Disable all other vertex attributes.
    for  (int va = 0; va < fMaxVertexAttribs; ++va) {
        if (va != posAttrIdx) {
            GL_CALL(DisableVertexAttribArray(va));
        }
    }

    fHWProgramID = 0;
}
void GL3CharacterRenderer::buildHead() {
	GL(GenVertexArrays(1, &headVao));
	GL(GenBuffers(1, &headVbo));
	GL(BindVertexArray(headVao));
	GL(BindBuffer(GL_ARRAY_BUFFER, headVbo));
	GL(VertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 40, 0));
	GL(VertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 40, (void *) 12));
	GL(VertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 40, (void *) 24));
	GL(EnableVertexAttribArray(0));
	GL(EnableVertexAttribArray(1));
	GL(EnableVertexAttribArray(2));
	GL(BindVertexArray(0));

	VertexData vertexData[36];
	int vertexIndices[6] = {0, 1, 2, 0, 2, 3};
	int index = 0;
	for (int d = 0; d < 6; d++) {
		vec3f normal(0.0);
		normal[d % 3] = DIRS[d][d % 3];
		vec3f vertices[4];
		for (int i = 0; i < 4; i++) {
			vertices[i] = vec3f(
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][0] - 0.5f) * HEAD_SIZE[0],
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][1] - 0.5f) * HEAD_SIZE[1],
				(DIR_QUAD_CORNER_CYCLES_3D[d][i][2] - 0.5f) * HEAD_SIZE[2] + HEAD_Z_OFFSET
			) * (1.0f / RESOLUTION);
		}
		for (int j = 0; j < 6; j++) {
			vertexData[index].xyz[0] = vertices[vertexIndices[j]][0];
			vertexData[index].xyz[1] = vertices[vertexIndices[j]][1];
			vertexData[index].xyz[2] = vertices[vertexIndices[j]][2];
			vertexData[index].nxyz[0] = normal[0];
			vertexData[index].nxyz[1] = normal[1];
			vertexData[index].nxyz[2] = normal[2];
			vertexData[index].rgba[0] = CHARACTER_COLOR[0];
			vertexData[index].rgba[1] = CHARACTER_COLOR[1];
			vertexData[index].rgba[2] = CHARACTER_COLOR[2];
			vertexData[index].rgba[3] = 1.0f;
			index++;
		}
	}

	GL(BufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW));
	GL(BindBuffer(GL_ARRAY_BUFFER, 0));
}
void GLInstancedRendering::flushInstanceAttribs(int baseInstance) {
    SkASSERT(fVertexArrayID);
    this->glGpu()->bindVertexArray(fVertexArrayID);

    SkASSERT(fInstanceBuffer);
    if (fInstanceAttribsBufferUniqueId != fInstanceBuffer->getUniqueID() ||
        fInstanceAttribsBaseInstance != baseInstance) {
        Instance* offsetInBuffer = (Instance*) nullptr + baseInstance;

        this->glGpu()->bindBuffer(kVertex_GrBufferType, fInstanceBuffer.get());

        // Info attrib.
        GL_CALL(EnableVertexAttribArray((int)Attrib::kInstanceInfo));
        GL_CALL(VertexAttribIPointer((int)Attrib::kInstanceInfo, 1, GR_GL_UNSIGNED_INT,
                                     sizeof(Instance), &offsetInBuffer->fInfo));
        GL_CALL(VertexAttribDivisor((int)Attrib::kInstanceInfo, 1));

        // Shape matrix attrib.
        GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeMatrixX));
        GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeMatrixY));
        GL_CALL(VertexAttribPointer((int)Attrib::kShapeMatrixX, 3, GR_GL_FLOAT, GR_GL_FALSE,
                                    sizeof(Instance), &offsetInBuffer->fShapeMatrix2x3[0]));
        GL_CALL(VertexAttribPointer((int)Attrib::kShapeMatrixY, 3, GR_GL_FLOAT, GR_GL_FALSE,
                                    sizeof(Instance), &offsetInBuffer->fShapeMatrix2x3[3]));
        GL_CALL(VertexAttribDivisor((int)Attrib::kShapeMatrixX, 1));
        GL_CALL(VertexAttribDivisor((int)Attrib::kShapeMatrixY, 1));

        // Color attrib.
        GL_CALL(EnableVertexAttribArray((int)Attrib::kColor));
        GL_CALL(VertexAttribPointer((int)Attrib::kColor, 4, GR_GL_UNSIGNED_BYTE, GR_GL_TRUE,
                                    sizeof(Instance), &offsetInBuffer->fColor));
        GL_CALL(VertexAttribDivisor((int)Attrib::kColor, 1));

        // Local rect attrib.
        GL_CALL(EnableVertexAttribArray((int)Attrib::kLocalRect));
        GL_CALL(VertexAttribPointer((int)Attrib::kLocalRect, 4, GR_GL_FLOAT, GR_GL_FALSE,
                                    sizeof(Instance), &offsetInBuffer->fLocalRect));
        GL_CALL(VertexAttribDivisor((int)Attrib::kLocalRect, 1));

        fInstanceAttribsBufferUniqueId = fInstanceBuffer->getUniqueID();
        fInstanceAttribsBaseInstance = baseInstance;
    }
}
void GrGpuGLShaders::resetContextHelper() {
    fHWGeometryState.fVertexLayout = 0;
    fHWGeometryState.fVertexOffset = ~0;
    GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
    for (int t = 0; t < kMaxTexCoords; ++t) {
        GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
    }
    GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION));

    fHWProgramID = 0;
}
Example #6
0
void GLCpuPosInstancedArraysBench::setupInstanceVbo(const GrGLInterface* gl,
                                                    const SkMatrix* viewMatrices) {
    // We draw all of the instances at a single place because we aren't allowed to have per vertex
    // per instance attributes
    SkPoint positions[kVerticesPerTri];
    positions[0].set(-1.0f, -1.0f);
    positions[1].set( 1.0f, -1.0f);
    positions[2].set( 1.0f,  1.0f);
    viewMatrices[0].mapPointsWithStride(positions, sizeof(SkPoint), kVerticesPerTri);

    // setup colors so we can detect we are actually drawing instances(the last triangle will be
    // a different color)
    GrGLfloat colors[kVerticesPerTri * kNumTri];
    for (uint32_t i = 0; i < kNumTri; i++) {
        // set colors
        uint32_t offset = i * kVerticesPerTri;
        float color = i == kNumTri - 1 ? 1.0f : 0.0f;
        colors[offset++] = color; colors[offset++] = 0.0f; colors[offset++] = 0.0f;
    }

    GrGLuint posVBO;
    // setup position VBO
    GR_GL_CALL(gl, GenBuffers(1, &posVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, posVBO));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(positions), positions, GR_GL_STATIC_DRAW));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 2 * sizeof(GrGLfloat),
                                       (GrGLvoid*)0));

    // setup color VBO
    GrGLuint instanceVBO;
    GR_GL_CALL(gl, GenBuffers(1, &instanceVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, instanceVBO));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(colors), colors, GR_GL_STATIC_DRAW));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 3 * sizeof(GrGLfloat),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribDivisor(1, 1));
    fBuffers.push_back(posVBO);
    fBuffers.push_back(instanceVBO);
}
Example #7
0
void GLCpuPosInstancedArraysBench::setupDoubleVbo(const GrGLInterface* gl,
                                                  const SkMatrix* viewMatrices) {
    // Constants for our various shader programs
    SkPoint positions[kVerticesPerTri * kNumTri];
    GrGLfloat colors[kVerticesPerTri * kNumTri * 3];
    for (uint32_t i = 0; i < kNumTri; i++) {
        SkPoint* position = &positions[i * kVerticesPerTri];
        position[0].set(-1.0f, -1.0f);
        position[1].set( 1.0f, -1.0f);
        position[2].set( 1.0f,  1.0f);
        viewMatrices[i].mapPointsWithStride(position, sizeof(SkPoint), kVerticesPerTri);

        // set colors
        float color = i == kNumTri - 1 ? 1.0f : 0.0f;
        uint32_t offset = i * kVerticesPerTri * 3;
        for (uint32_t j = 0; j < kVerticesPerTri; j++) {
            colors[offset++] = color; colors[offset++] = 0.0f; colors[offset++] = 0.0f;
        }
    }

    GrGLuint posVBO, colorVBO;
    // setup position VBO
    GR_GL_CALL(gl, GenBuffers(1, &posVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, posVBO));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 2 * sizeof(GrGLfloat),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(positions), positions, GR_GL_STATIC_DRAW));

    // setup color VBO
    GR_GL_CALL(gl, GenBuffers(1, &colorVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, colorVBO));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 3 * sizeof(GrGLfloat),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(colors), colors, GR_GL_STATIC_DRAW));

    fBuffers.push_back(posVBO);
    fBuffers.push_back(colorVBO);
}
Example #8
0
int
rb_vertex_attrib_array
  (struct rb_vertex_array* array,
   struct rb_buffer* buffer,
   int count,
   const struct rb_buffer_attrib* attrib)
{
  intptr_t offset = 0;
  int i = 0;
  int err = 0;

  if(!array
  || !buffer
  || !attrib
  || count < 0
  || buffer->target != GL_ARRAY_BUFFER)
    goto error;

  OGL(BindVertexArray(array->name));
  OGL(BindBuffer(buffer->target, buffer->name));

  for(i=0; i < count; ++i) {

    if(attrib[i].type == RB_UNKNOWN_TYPE) {
      OGL(BindBuffer
        (buffer->target, 
         array->ctxt->state_cache.buffer_binding[buffer->binding]));
      goto error;
    }

    offset = attrib[i].offset;
    OGL(EnableVertexAttribArray(attrib[i].index));
    OGL(VertexAttribPointer
        (attrib[i].index,
         ogl3_attrib_nb_components(attrib[i].type),
         GL_FLOAT,
         GL_FALSE,
         attrib[i].stride,
         (void*)offset));
  }

  OGL(BindVertexArray(array->ctxt->state_cache.vertex_array_binding));
  OGL(BindBuffer
    (buffer->target, array->ctxt->state_cache.buffer_binding[buffer->binding]));

exit:
  return err;

error:
  err = -1;
  goto exit;
}
Example #9
0
void GLVec4ScalarBench::setupSingleVbo(const GrGLInterface* gl, const SkMatrix* viewMatrices) {
    // triangles drawn will alternate between the top-right half of the screen and the bottom-left
    // half of the screen
    Vertex vertices[kVerticesPerTri * kNumTriPerDraw];
    for (uint32_t i = 0; i < kNumTriPerDraw; i++) {
        Vertex* v = &vertices[i * kVerticesPerTri];
        if (i % 2 == 0) {
            v[0].fPositions.set(-1.0f, -1.0f);
            v[1].fPositions.set( 1.0f, -1.0f);
            v[2].fPositions.set( 1.0f,  1.0f);
        } else {
            v[0].fPositions.set(-1.0f, -1.0f);
            v[1].fPositions.set( 1.0f, 1.0f);
            v[2].fPositions.set( -1.0f, 1.0f);
        }
        SkPoint* position = reinterpret_cast<SkPoint*>(v);
        viewMatrices[i].mapPointsWithStride(position, sizeof(Vertex), kVerticesPerTri);

        GrGLfloat color[3] = {1.0f, 0.0f, 1.0f};
        for (uint32_t j = 0; j < kVerticesPerTri; j++) {
            v->fColors[0] = color[0];
            v->fColors[1] = color[1];
            v->fColors[2] = color[2];
            v++;
        }
    }

    GR_GL_CALL(gl, GenBuffers(1, &fVboId));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVboId));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)(sizeof(SkPoint))));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(vertices), vertices, GR_GL_STATIC_DRAW));
}
Example #10
0
void GrGLAttribArrayState::set(const GrGpuGL* gpu,
                               int index,
                               GrGLVertexBuffer* buffer,
                               GrGLint size,
                               GrGLenum type,
                               GrGLboolean normalized,
                               GrGLsizei stride,
                               GrGLvoid* offset) {
    SkASSERT(index >= 0 && index < fAttribArrayStates.count());
    AttribArrayState* array = &fAttribArrayStates[index];
    if (!array->fEnableIsValid || !array->fEnabled) {
        GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
        array->fEnableIsValid = true;
        array->fEnabled = true;
    }
    if (!array->fAttribPointerIsValid ||
        array->fVertexBufferID != buffer->bufferID() ||
        array->fSize != size ||
        array->fNormalized != normalized ||
        array->fStride != stride ||
        array->fOffset != offset) {

        buffer->bind();
        GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
                                                           size,
                                                           type,
                                                           normalized,
                                                           stride,
                                                           offset));
        array->fAttribPointerIsValid = true;
        array->fVertexBufferID = buffer->bufferID();
        array->fSize = size;
        array->fNormalized = normalized;
        array->fStride = stride;
        array->fOffset = offset;
    }
}
void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) {

    int newColorOffset;
    int newCoverageOffset;
    int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
    int newEdgeOffset;

    GrVertexLayout currLayout = this->getVertexLayout();

    GrGLsizei newStride = GrDrawState::VertexSizeAndOffsetsByIdx(currLayout,
                                                                 newTexCoordOffsets,
                                                                 &newColorOffset,
                                                                 &newCoverageOffset,
                                                                 &newEdgeOffset);
    int oldColorOffset;
    int oldCoverageOffset;
    int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
    int oldEdgeOffset;

    GrGLsizei oldStride = GrDrawState::VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
                                                                 oldTexCoordOffsets,
                                                                 &oldColorOffset,
                                                                 &oldCoverageOffset,
                                                                 &oldEdgeOffset);

    int extraVertexOffset;
    this->setBuffers(info.isIndexed(), &extraVertexOffset, startIndexOffset);

    GrGLenum scalarType;
    bool texCoordNorm;
    if (currLayout & GrDrawState::kTextFormat_VertexLayoutBit) {
        scalarType = TEXT_COORDS_GL_TYPE;
        texCoordNorm = SkToBool(TEXT_COORDS_ARE_NORMALIZED);
    } else {
        scalarType = GR_GL_FLOAT;
        texCoordNorm = false;
    }

    size_t vertexOffset = (info.startVertex() + extraVertexOffset) * newStride;

    // all the Pointers must be set if any of these are true
    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
                             vertexOffset != fHWGeometryState.fVertexOffset ||
                             newStride != oldStride;

    // position and tex coord offsets change if above conditions are true
    // or the type/normalization changed based on text vs nontext type coords.
    bool posAndTexChange = allOffsetsChange ||
                           (((TEXT_COORDS_GL_TYPE != GR_GL_FLOAT) || TEXT_COORDS_ARE_NORMALIZED) &&
                                (GrDrawState::kTextFormat_VertexLayoutBit &
                                  (fHWGeometryState.fVertexLayout ^ currLayout)));

    if (posAndTexChange) {
        int idx = GrGLProgram::PositionAttributeIdx();
        GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride,
                                  (GrGLvoid*)vertexOffset));
        fHWGeometryState.fVertexOffset = vertexOffset;
    }

    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        if (newTexCoordOffsets[t] > 0) {
            GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
            int idx = GrGLProgram::TexCoordAttributeIdx(t);
            if (oldTexCoordOffsets[t] <= 0) {
                GL_CALL(EnableVertexAttribArray(idx));
                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
                                          newStride, texCoordOffset));
            } else if (posAndTexChange ||
                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
                                          newStride, texCoordOffset));
            }
        } else if (oldTexCoordOffsets[t] > 0) {
            GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
        }
    }

    if (newColorOffset > 0) {
        GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
        int idx = GrGLProgram::ColorAttributeIdx();
        if (oldColorOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                      true, newStride, colorOffset));
        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                      true, newStride, colorOffset));
        }
    } else if (oldColorOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
    }

    if (newCoverageOffset > 0) {
        GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset);
        int idx = GrGLProgram::CoverageAttributeIdx();
        if (oldCoverageOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, coverageOffset));
        } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, coverageOffset));
        }
    } else if (oldCoverageOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
    }

    if (newEdgeOffset > 0) {
        GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
        int idx = GrGLProgram::EdgeAttributeIdx();
        if (oldEdgeOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
                                        false, newStride, edgeOffset));
        } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
                                        false, newStride, edgeOffset));
        }
    } else if (oldEdgeOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
    }

    fHWGeometryState.fVertexLayout = currLayout;
    fHWGeometryState.fArrayPtrsDirty = false;
}
Example #12
0
void cShaderProgram::EnableVertexAttribArray( const std::string& Name ) {
	EnableVertexAttribArray( AttributeLocation( Name ) );
}
Example #13
0
GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index)
{
    CONTEXT_EXEC(EnableVertexAttribArray(index));
}
void GrGpuGLShaders::setupGeometry(int* startVertex,
                                    int* startIndex,
                                    int vertexCount,
                                    int indexCount) {

    int newColorOffset;
    int newTexCoordOffsets[kMaxTexCoords];

    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
                                                  newTexCoordOffsets,
                                                  &newColorOffset);
    int oldColorOffset;
    int oldTexCoordOffsets[kMaxTexCoords];
    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
                                                  oldTexCoordOffsets,
                                                  &oldColorOffset);
    bool indexed = NULL != startIndex;

    int extraVertexOffset;
    int extraIndexOffset;
    setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);

    GrGLenum scalarType;
    bool texCoordNorm;
    if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
        scalarType = GrGLTextType;
        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
    } else {
        scalarType = GrGLType;
        texCoordNorm = false;
    }

    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
    *startVertex = 0;
    if (indexed) {
        *startIndex += extraIndexOffset;
    }

    // all the Pointers must be set if any of these are true
    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
                             vertexOffset != fHWGeometryState.fVertexOffset ||
                             newStride != oldStride;

    // position and tex coord offsets change if above conditions are true
    // or the type/normalization changed based on text vs nontext type coords.
    bool posAndTexChange = allOffsetsChange ||
                           (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
                                (kTextFormat_VertexLayoutBit &
                                  (fHWGeometryState.fVertexLayout ^
                                   fGeometrySrc.fVertexLayout)));

    if (posAndTexChange) {
        GR_GL(VertexAttribPointer(POS_ATTR_LOCATION, 2, scalarType,
                                  false, newStride, (GrGLvoid*)vertexOffset));
        fHWGeometryState.fVertexOffset = vertexOffset;
    }

    for (int t = 0; t < kMaxTexCoords; ++t) {
        if (newTexCoordOffsets[t] > 0) {
            GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
            if (oldTexCoordOffsets[t] <= 0) {
                GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
                GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
                                          texCoordNorm, newStride, texCoordOffset));
            } else if (posAndTexChange ||
                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
                GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
                                          texCoordNorm, newStride, texCoordOffset));
            }
        } else if (oldTexCoordOffsets[t] > 0) {
            GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
        }
    }

    if (newColorOffset > 0) {
        GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
        if (oldColorOffset <= 0) {
            GR_GL(EnableVertexAttribArray(COL_ATTR_LOCATION));
            GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
                                      GR_GL_UNSIGNED_BYTE,
                                      true, newStride, colorOffset));
        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
            GR_GL(VertexAttribPointer(COL_ATTR_LOCATION, 4,
                                      GR_GL_UNSIGNED_BYTE,
                                      true, newStride, colorOffset));
        }
    } else if (oldColorOffset > 0) {
        GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
    }

    fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
    fHWGeometryState.fArrayPtrsDirty = false;
}
void GLInstancedRendering::onBeginFlush(GrResourceProvider* rp) {
    // Count what there is to draw.
    BatchList::Iter iter;
    iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
    int numGLInstances = 0;
    int numGLDrawCmds = 0;
    while (Batch* b = iter.get()) {
        GLBatch* batch = static_cast<GLBatch*>(b);
        iter.next();

        numGLInstances += batch->fNumDraws;
        numGLDrawCmds += batch->numGLCommands();
    }
    if (!numGLDrawCmds) {
        return;
    }
    SkASSERT(numGLInstances);

    // Lazily create a vertex array object.
    if (!fVertexArrayID) {
        GL_CALL(GenVertexArrays(1, &fVertexArrayID));
        if (!fVertexArrayID) {
            return;
        }
        this->glGpu()->bindVertexArray(fVertexArrayID);

        // Attach our index buffer to the vertex array.
        SkASSERT(!this->indexBuffer()->isCPUBacked());
        GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
                           static_cast<const GrGLBuffer*>(this->indexBuffer())->bufferID()));

        // Set up the non-instanced attribs.
        this->glGpu()->bindBuffer(kVertex_GrBufferType, this->vertexBuffer());
        GL_CALL(EnableVertexAttribArray((int)Attrib::kShapeCoords));
        GL_CALL(VertexAttribPointer((int)Attrib::kShapeCoords, 2, GR_GL_FLOAT, GR_GL_FALSE,
                                    sizeof(ShapeVertex), (void*) offsetof(ShapeVertex, fX)));
        GL_CALL(EnableVertexAttribArray((int)Attrib::kVertexAttrs));
        GL_CALL(VertexAttribIPointer((int)Attrib::kVertexAttrs, 1, GR_GL_INT, sizeof(ShapeVertex),
                                     (void*) offsetof(ShapeVertex, fAttrs)));

        SkASSERT(SK_InvalidUniqueID == fInstanceAttribsBufferUniqueId);
    }

    // Create and map instance and draw-indirect buffers.
    SkASSERT(!fInstanceBuffer);
    fInstanceBuffer.reset(
        rp->createBuffer(sizeof(Instance) * numGLInstances, kVertex_GrBufferType,
                         kDynamic_GrAccessPattern,
                         GrResourceProvider::kNoPendingIO_Flag |
                         GrResourceProvider::kRequireGpuMemory_Flag));
    if (!fInstanceBuffer) {
        return;
    }

    SkASSERT(!fDrawIndirectBuffer);
    fDrawIndirectBuffer.reset(
        rp->createBuffer(sizeof(GrGLDrawElementsIndirectCommand) * numGLDrawCmds,
                         kDrawIndirect_GrBufferType, kDynamic_GrAccessPattern,
                         GrResourceProvider::kNoPendingIO_Flag |
                         GrResourceProvider::kRequireGpuMemory_Flag));
    if (!fDrawIndirectBuffer) {
        return;
    }

    Instance* glMappedInstances = static_cast<Instance*>(fInstanceBuffer->map());
    int glInstancesIdx = 0;

    auto* glMappedCmds = static_cast<GrGLDrawElementsIndirectCommand*>(fDrawIndirectBuffer->map());
    int glDrawCmdsIdx = 0;

    bool baseInstanceSupport = this->glGpu()->glCaps().baseInstanceSupport();

    if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
        fGLDrawCmdsInfo.reset(numGLDrawCmds);
    }

    // Generate the instance and draw-indirect buffer contents based on the tracked batches.
    iter.init(this->trackedBatches(), BatchList::Iter::kHead_IterStart);
    while (Batch* b = iter.get()) {
        GLBatch* batch = static_cast<GLBatch*>(b);
        iter.next();

        batch->fEmulatedBaseInstance = baseInstanceSupport ? 0 : glInstancesIdx;
        batch->fGLDrawCmdsIdx = glDrawCmdsIdx;

        const Batch::Draw* draw = batch->fHeadDraw;
        SkASSERT(draw);
        do {
            int instanceCount = 0;
            IndexRange geometry = draw->fGeometry;
            SkASSERT(!geometry.isEmpty());

            do {
                glMappedInstances[glInstancesIdx + instanceCount++] = draw->fInstance;
                draw = draw->fNext;
            } while (draw && draw->fGeometry == geometry);

            GrGLDrawElementsIndirectCommand& glCmd = glMappedCmds[glDrawCmdsIdx];
            glCmd.fCount = geometry.fCount;
            glCmd.fInstanceCount = instanceCount;
            glCmd.fFirstIndex = geometry.fStart;
            glCmd.fBaseVertex = 0;
            glCmd.fBaseInstance = baseInstanceSupport ? glInstancesIdx : 0;

            if (GR_GL_LOG_INSTANCED_BATCHES || !baseInstanceSupport) {
                fGLDrawCmdsInfo[glDrawCmdsIdx].fInstanceCount = instanceCount;
#if GR_GL_LOG_INSTANCED_BATCHES
                fGLDrawCmdsInfo[glDrawCmdsIdx].fGeometry = geometry;
#endif
            }

            glInstancesIdx += instanceCount;
            ++glDrawCmdsIdx;
        } while (draw);
    }

    SkASSERT(glDrawCmdsIdx == numGLDrawCmds);
    fDrawIndirectBuffer->unmap();

    SkASSERT(glInstancesIdx == numGLInstances);
    fInstanceBuffer->unmap();
}
Example #16
0
void GLGpuPosInstancedArraysBench::setup(const GrGLInterface* gl) {
    setup_framebuffer(gl, kScreenWidth, kScreenHeight);

    // compile and use shaders
    GrGLint shaderProgram = compile_shader(gl, gpu_vertex_shader, fragment_shader);

    // translations
    int index = 0;
    GrGLfloat viewMatrices[fNumQuads * fSkMatrixNumCells];
    setup_matrices(fNumQuads, [&index, &viewMatrices](const SkMatrix& m) {
        GrGLGetMatrix<3>(&viewMatrices[index], m);
        index += fSkMatrixNumCells;
    });

    // Constants for our various shader programs
    GrGLfloat quad_vertices[] = {
            // Positions // Colors
            -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
             1.0f, -1.0f,  0.0f, 1.0f, 0.0f,
            -1.0f, -1.0f,  0.0f, 0.0f, 1.0f,

            -1.0f,  1.0f,  1.0f, 0.0f, 0.0f,
             1.0f, -1.0f,  0.0f, 1.0f, 0.0f,
             1.0f,  1.0f,  0.0f, 1.0f, 1.0f
    };

    // update vertex data
    GrGLuint quadVAO, quadVBO;
    GR_GL_CALL(gl, GenVertexArrays(1, &quadVAO));
    GR_GL_CALL(gl, GenBuffers(1, &quadVBO));
    GR_GL_CALL(gl, BindVertexArray(quadVAO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, quadVBO));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeof(GrGLfloat), (GrGLvoid*)0));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, 5 * sizeof(GrGLfloat), (GrGLvoid*)(2 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GR_GL_STATIC_DRAW));

    // Also set instance data
    GrGLuint instanceVBO;
    GR_GL_CALL(gl, GenBuffers(1, &instanceVBO));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, instanceVBO));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(GrGLfloat) * fSkMatrixNumCells * fNumQuads,
                              &viewMatrices[0], GR_GL_STATIC_DRAW));
    GR_GL_CALL(gl, EnableVertexAttribArray(2));
    GR_GL_CALL(gl, EnableVertexAttribArray(3));
    GR_GL_CALL(gl, EnableVertexAttribArray(4));
    GR_GL_CALL(gl, VertexAttribPointer(2, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribPointer(3, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)(3 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, VertexAttribPointer(4, 3, GR_GL_FLOAT, GR_GL_FALSE, 9 * sizeof(GrGLfloat), (GrGLvoid*)(6 * sizeof(GrGLfloat))));
    GR_GL_CALL(gl, VertexAttribDivisor(2, 1));
    GR_GL_CALL(gl, VertexAttribDivisor(3, 1));
    GR_GL_CALL(gl, VertexAttribDivisor(4, 1));

    // draw
    GR_GL_CALL(gl, ClearColor(0.03f, 0.03f, 0.03f, 1.0f));
    GR_GL_CALL(gl, Clear(GR_GL_COLOR_BUFFER_BIT));

    // set us up to draw
    GR_GL_CALL(gl, UseProgram(shaderProgram));
    GR_GL_CALL(gl, BindVertexArray(quadVAO));
}
Example #17
0
void GrGpuGLShaders::setupGeometry(int* startVertex,
                                   int* startIndex,
                                   int vertexCount,
                                   int indexCount) {

    int newColorOffset;
    int newCoverageOffset;
    int newTexCoordOffsets[GrDrawState::kMaxTexCoords];
    int newEdgeOffset;

    GrGLsizei newStride = VertexSizeAndOffsetsByIdx(
                              this->getGeomSrc().fVertexLayout,
                              newTexCoordOffsets,
                              &newColorOffset,
                              &newCoverageOffset,
                              &newEdgeOffset);
    int oldColorOffset;
    int oldCoverageOffset;
    int oldTexCoordOffsets[GrDrawState::kMaxTexCoords];
    int oldEdgeOffset;

    GrGLsizei oldStride = VertexSizeAndOffsetsByIdx(
                              fHWGeometryState.fVertexLayout,
                              oldTexCoordOffsets,
                              &oldColorOffset,
                              &oldCoverageOffset,
                              &oldEdgeOffset);
    bool indexed = NULL != startIndex;

    int extraVertexOffset;
    int extraIndexOffset;
    this->setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);

    GrGLenum scalarType;
    bool texCoordNorm;
    if (this->getGeomSrc().fVertexLayout & kTextFormat_VertexLayoutBit) {
        scalarType = GrGLTextType;
        texCoordNorm = GR_GL_TEXT_TEXTURE_NORMALIZED;
    } else {
        scalarType = GrGLType;
        texCoordNorm = false;
    }

    size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
    *startVertex = 0;
    if (indexed) {
        *startIndex += extraIndexOffset;
    }

    // all the Pointers must be set if any of these are true
    bool allOffsetsChange =  fHWGeometryState.fArrayPtrsDirty ||
                             vertexOffset != fHWGeometryState.fVertexOffset ||
                             newStride != oldStride;

    // position and tex coord offsets change if above conditions are true
    // or the type/normalization changed based on text vs nontext type coords.
    bool posAndTexChange = allOffsetsChange ||
                           (((GrGLTextType != GrGLType) || GR_GL_TEXT_TEXTURE_NORMALIZED) &&
                            (kTextFormat_VertexLayoutBit &
                             (fHWGeometryState.fVertexLayout ^
                              this->getGeomSrc().fVertexLayout)));

    if (posAndTexChange) {
        int idx = GrGLProgram::PositionAttributeIdx();
        GL_CALL(VertexAttribPointer(idx, 2, scalarType, false, newStride,
                                    (GrGLvoid*)vertexOffset));
        fHWGeometryState.fVertexOffset = vertexOffset;
    }

    for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
        if (newTexCoordOffsets[t] > 0) {
            GrGLvoid* texCoordOffset = (GrGLvoid*)(vertexOffset + newTexCoordOffsets[t]);
            int idx = GrGLProgram::TexCoordAttributeIdx(t);
            if (oldTexCoordOffsets[t] <= 0) {
                GL_CALL(EnableVertexAttribArray(idx));
                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
                                            newStride, texCoordOffset));
            } else if (posAndTexChange ||
                       newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
                GL_CALL(VertexAttribPointer(idx, 2, scalarType, texCoordNorm,
                                            newStride, texCoordOffset));
            }
        } else if (oldTexCoordOffsets[t] > 0) {
            GL_CALL(DisableVertexAttribArray(GrGLProgram::TexCoordAttributeIdx(t)));
        }
    }

    if (newColorOffset > 0) {
        GrGLvoid* colorOffset = (int8_t*)(vertexOffset + newColorOffset);
        int idx = GrGLProgram::ColorAttributeIdx();
        if (oldColorOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, colorOffset));
        } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
            GL_CALL(VertexAttribPointer(idx, 4, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, colorOffset));
        }
    } else if (oldColorOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::ColorAttributeIdx()));
    }

    if (newCoverageOffset > 0) {
        // bind a single channel, they should all have the same value.
        GrGLvoid* coverageOffset = (int8_t*)(vertexOffset + newCoverageOffset);
        int idx = GrGLProgram::CoverageAttributeIdx();
        if (oldCoverageOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, coverageOffset));
        } else if (allOffsetsChange || newCoverageOffset != oldCoverageOffset) {
            GL_CALL(VertexAttribPointer(idx, 1, GR_GL_UNSIGNED_BYTE,
                                        true, newStride, coverageOffset));
        }
    } else if (oldCoverageOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::CoverageAttributeIdx()));
    }

    if (newEdgeOffset > 0) {
        GrGLvoid* edgeOffset = (int8_t*)(vertexOffset + newEdgeOffset);
        int idx = GrGLProgram::EdgeAttributeIdx();
        if (oldEdgeOffset <= 0) {
            GL_CALL(EnableVertexAttribArray(idx));
            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
                                        false, newStride, edgeOffset));
        } else if (allOffsetsChange || newEdgeOffset != oldEdgeOffset) {
            GL_CALL(VertexAttribPointer(idx, 4, scalarType,
                                        false, newStride, edgeOffset));
        }
    } else if (oldEdgeOffset > 0) {
        GL_CALL(DisableVertexAttribArray(GrGLProgram::EdgeAttributeIdx()));
    }

    fHWGeometryState.fVertexLayout = this->getGeomSrc().fVertexLayout;
    fHWGeometryState.fArrayPtrsDirty = false;
}