void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { GrDrawState* drawState = this->drawState(); GrColor color = drawState->getColor(); set_vertex_attributes(drawState, SkToBool(localRect), color); AutoReleaseGeometry geo(this, 4, 0); if (!geo.succeeded()) { SkDebugf("Failed to get space for vertices!\n"); return; } // Go to device coords to allow batching across matrix changes SkMatrix matrix = drawState->getViewMatrix(); // When the caller has provided an explicit source rect for a stage then we don't want to // modify that stage's matrix. Otherwise if the effect is generating its source rect from // the vertex positions then we have to account for the view matrix change. GrDrawState::AutoViewMatrixRestore avmr; if (!avmr.setIdentity(drawState)) { return; } size_t vstride = drawState->getVertexStride(); geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride); matrix.mapPointsWithStride(geo.positions(), vstride, 4); SkRect devBounds; // since we already computed the dev verts, set the bounds hint. This will help us avoid // unnecessary clipping in our onDraw(). get_vertex_bounds(geo.vertices(), vstride, 4, &devBounds); if (localRect) { static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) + kLocalOffset); coords->setRectFan(localRect->fLeft, localRect->fTop, localRect->fRight, localRect->fBottom, vstride); if (localMatrix) { localMatrix->mapPointsWithStride(coords, vstride, 4); } } static const int kColorOffset = sizeof(SkPoint); GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + kColorOffset); for (int i = 0; i < 4; ++i) { *vertColor = color; vertColor = (GrColor*) ((intptr_t) vertColor + vstride); } this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds); // to ensure that stashing the drawState ptr is valid SkASSERT(this->drawState() == drawState); }
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags, GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff, const GrDrawTargetCaps& caps) : INHERITED(drawState) { fColor = drawState.getColor(); fCoverage = drawState.getCoverage(); fViewMatrix = drawState.getViewMatrix(); fBlendConstant = drawState.getBlendConstant(); fFlagBits = drawState.getFlagBits(); fVAPtr = drawState.getVertexAttribs(); fVACount = drawState.getVertexAttribCount(); fVAStride = drawState.getVertexStride(); fStencilSettings = drawState.getStencil(); fDrawFace = drawState.getDrawFace(); fBlendOptFlags = blendOptFlags; fSrcBlend = optSrcCoeff; fDstBlend = optDstCoeff; memcpy(fFixedFunctionVertexAttribIndices, drawState.getFixedFunctionVertexAttribIndices(), sizeof(fFixedFunctionVertexAttribIndices)); fInputColorIsUsed = true; fInputCoverageIsUsed = true; if (drawState.hasGeometryProcessor()) { fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor()))); } else { fGeometryProcessor.reset(NULL); } this->copyEffectiveColorStages(drawState); this->copyEffectiveCoverageStages(drawState); this->adjustFromBlendOpts(); this->getStageStats(); this->setOutputStateInfo(caps); };