void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
                                                             GrGLenum genMode, GrGLint components,
                                                             const SkMatrix& matrix) {
    float coefficients[3 * 3];
    SkASSERT(components >= 1 && components <= 3);

    coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]);
    coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]);
    coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]);

    if (components >= 2) {
        coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]);
        coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]);
        coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]);
    }

    if (components >= 3) {
        coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]);
        coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]);
        coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]);
    }
    SkDEBUGCODE(verify_floats(coefficients, components * 3));

    GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coefficients));
}
void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix,
                                            const SkISize& renderTargetSize,
                                            GrSurfaceOrigin renderTargetOrigin) {

    SkASSERT(this->gpu()->glCaps().shaderCaps()->pathRenderingSupport());

    if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin &&
        renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize &&
        matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) {
        return;
    }

    fHWProjectionMatrixState.fViewMatrix = matrix;
    fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize;
    fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin;

    float glMatrix[4 * 4];
    fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix);
    SkDEBUGCODE(verify_floats(glMatrix, SK_ARRAY_COUNT(glMatrix)));
    GL_CALL(MatrixLoadf(GR_GL_PATH_PROJECTION, glMatrix));
}
Exemple #3
0
void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
                                    const GrPrimitiveProcessor& primProc,
                                    const GrStencilSettings& stencil, const GrPathRange* pathRange,
                                    const void* indices, PathIndexType indexType,
                                    const float transformValues[], PathTransformType transformType,
                                    int count) {
    SkDEBUGCODE(verify_floats(transformValues, gXformType2ComponentCount[transformType] * count));

    if (!this->gpu()->flushGLState(pipeline, primProc)) {
        return;
    }
    this->flushPathStencilSettings(stencil);
    SkASSERT(!fHWPathStencilSettings.isTwoSided());


    const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRange);

    GrGLenum fillMode =
        gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.front().fPassOp);
    GrGLint writeMask = fHWPathStencilSettings.front().fWriteMask;

    if (glPathRange->shouldStroke()) {
        if (glPathRange->shouldFill()) {
            GL_CALL(StencilFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, gXformType2GLType[transformType],
                            transformValues));
        }
        GL_CALL(StencilThenCoverStrokePathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    } else {
        GL_CALL(StencilThenCoverFillPathInstanced(
                            count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
                            fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
                            gXformType2GLType[transformType], transformValues));
    }
}
Exemple #4
0
void GrGLPath::InitPathObjectPathData(GrGLGpu* gpu,
                                      GrGLuint pathID,
                                      const SkPath& skPath) {
    SkASSERT(!skPath.isEmpty());

#ifdef SK_SCALAR_IS_FLOAT
    // This branch does type punning, converting SkPoint* to GrGLfloat*.
    if ((skPath.getSegmentMasks() & SkPath::kConic_SegmentMask) == 0) {
        int verbCnt = skPath.countVerbs();
        int pointCnt = skPath.countPoints();
        int coordCnt = pointCnt * 2;
        SkSTArray<16, GrGLubyte, true> pathCommands(verbCnt);
        SkSTArray<16, GrGLfloat, true> pathCoords(coordCnt);

        static_assert(sizeof(SkPoint) == sizeof(GrGLfloat) * 2, "sk_point_not_two_floats");

        pathCommands.resize_back(verbCnt);
        pathCoords.resize_back(coordCnt);
        skPath.getPoints(reinterpret_cast<SkPoint*>(&pathCoords[0]), pointCnt);
        skPath.getVerbs(&pathCommands[0], verbCnt);

        SkDEBUGCODE(int verbCoordCnt = 0);
        for (int i = 0; i < verbCnt; ++i) {
            SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
            pathCommands[i] = verb_to_gl_path_cmd(v);
            SkDEBUGCODE(verbCoordCnt += num_coords(v));
        }
        SkASSERT(verbCnt == pathCommands.count());
        SkASSERT(verbCoordCnt == pathCoords.count());
        SkDEBUGCODE(verify_floats(&pathCoords[0], pathCoords.count()));
        GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count(), &pathCommands[0],
                                                    pathCoords.count(), GR_GL_FLOAT,
                                                    &pathCoords[0]));
        return;
    }
#endif
    SkAssertResult(init_path_object_for_general_path<false>(gpu, pathID, skPath));
}