bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, GrPathFill fill, const GrVec* translate, GrDrawTarget* target, GrDrawState::StageMask stageMask, bool antiAlias) { const SkPath* path = &origPath; if (path->isEmpty()) { return true; } GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); GrDrawState* drawState = target->drawState(); GrMatrix vm = drawState->getViewMatrix(); if (NULL != translate) { vm.postTranslate(translate->fX, translate->fY); } GrMatrix ivm; if (vm.invert(&ivm)) { drawState->preConcatSamplerMatrices(stageMask, ivm); } drawState->viewMatrix()->reset(); GrVertexLayout layout = 0; for (int s = 0; s < GrDrawState::kNumStages; ++s) { if ((1 << s) & stageMask) { layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s); } } layout |= GrDrawTarget::kEdge_VertexLayoutBit; // We use the fact that SkPath::transform path does subdivision based on // perspective. Otherwise, we apply the view matrix when copying to the // segment representation. SkPath tmpPath; if (vm.hasPerspective()) { origPath.transform(vm, &tmpPath); path = &tmpPath; vm.reset(); } QuadVertex *verts; uint16_t* idxs; int vCount; int iCount; enum { kPreallocSegmentCnt = 512 / sizeof(Segment), }; SkSTArray<kPreallocSegmentCnt, Segment, true> segments; SkPoint fanPt; if (!get_segments(*path, vm, &segments, &fanPt, &vCount, &iCount)) { return false; } GrDrawTarget::AutoReleaseGeometry arg(target, layout, vCount, iCount); if (!arg.succeeded()) { return false; } verts = reinterpret_cast<QuadVertex*>(arg.vertices()); idxs = reinterpret_cast<uint16_t*>(arg.indices()); create_vertices(segments, fanPt, verts, idxs); drawState->setVertexEdgeType(GrDrawState::kQuad_EdgeType); target->drawIndexed(kTriangles_PrimitiveType, 0, // start vertex 0, // start index vCount, iCount); return true; }
void GrGpuGL::flushViewMatrix(DrawType type) { const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget()); SkISize viewportSize; const GrGLIRect& viewport = rt->getViewport(); viewportSize.set(viewport.fWidth, viewport.fHeight); const GrMatrix& vm = this->getDrawState().getViewMatrix(); if (kStencilPath_DrawType == type) { if (fHWPathMatrixState.fViewMatrix != vm || fHWPathMatrixState.fRTSize != viewportSize) { // rescale the coords from skia's "device" coords to GL's normalized coords, // and perform a y-flip. GrMatrix m; m.setScale(GrIntToScalar(2) / rt->width(), GrIntToScalar(-2) / rt->height()); m.postTranslate(-GR_Scalar1, GR_Scalar1); m.preConcat(vm); // GL wants a column-major 4x4. GrGLfloat mv[] = { // col 0 GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), 0, GrScalarToFloat(m[GrMatrix::kMPersp0]), // col 1 GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), 0, GrScalarToFloat(m[GrMatrix::kMPersp1]), // col 2 0, 0, 0, 0, // col3 GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), 0.0f, GrScalarToFloat(m[GrMatrix::kMPersp2]) }; GL_CALL(MatrixMode(GR_GL_PROJECTION)); GL_CALL(LoadMatrixf(mv)); fHWPathMatrixState.fViewMatrix = vm; fHWPathMatrixState.fRTSize = viewportSize; } } else if (!fCurrentProgram->fViewMatrix.cheapEqualTo(vm) || fCurrentProgram->fViewportSize != viewportSize) { GrMatrix m; m.setAll( GrIntToScalar(2) / viewportSize.fWidth, 0, -GR_Scalar1, 0,-GrIntToScalar(2) / viewportSize.fHeight, GR_Scalar1, 0, 0, GrMatrix::I()[8]); m.setConcat(m, vm); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrGLfloat mt[] = { GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), GrScalarToFloat(m[GrMatrix::kMPersp0]), GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), GrScalarToFloat(m[GrMatrix::kMPersp1]), GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), GrScalarToFloat(m[GrMatrix::kMPersp2]) }; fCurrentProgram->fUniformManager.setMatrix3f(fCurrentProgram->fUniforms.fViewMatrixUni, mt); fCurrentProgram->fViewMatrix = vm; fCurrentProgram->fViewportSize = viewportSize; } }