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;
    }
}
예제 #2
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);
}
예제 #3
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));
}