GrNonAAFillRectOp.cpp revision 08d141534cb24a491edbf5db31cdc7b966ec8d72
19c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt/* 29c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * Copyright 2015 Google Inc. 39c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * 49c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * Use of this source code is governed by a BSD-style license that can be 59c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt * found in the LICENSE file. 69c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt */ 79c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 8bcf33d5c06f7560039797b6023f14466c75598edjoshualitt#include "GrNonAAFillRectBatch.h" 99c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 107539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon#include "GrBatchFlushState.h" 119c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrColor.h" 129c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrDefaultGeoProcFactory.h" 139c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrPrimitiveProcessor.h" 142244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt#include "GrResourceProvider.h" 15ae5b2c623b22b24ea7c0d6200298e5bc366faa63joshualitt#include "GrQuad.h" 1616b991390bb988b194a868ab8de66db4c21c7c13bsalomon#include "GrVertexBatch.h" 179c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 1808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonstatic const int kVertsPerInstance = 4; 1908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonstatic const int kIndicesPerInstance = 6; 202244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 212244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt/** We always use per-vertex colors so that rects can be batched across color changes. Sometimes 222244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt we have explicit local coords and sometimes not. We *could* always provide explicit local 232244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt coords and just duplicate the positions when the caller hasn't provided a local coord rect, 242244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt but we haven't seen a use case which frequently switches between local rect and no local 252244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt rect draws. 262244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 272244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt The vertex attrib order is always pos, color, [local coords]. 282244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt */ 2906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemanstatic sk_sp<GrGeometryProcessor> make_gp(const SkMatrix& viewMatrix, 3006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman bool readsCoverage, 3106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman bool hasExplicitLocalCoords, 3206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman const SkMatrix* localMatrix) { 332244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt using namespace GrDefaultGeoProcFactory; 342244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt Color color(Color::kAttribute_Type); 352244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt Coverage coverage(readsCoverage ? Coverage::kSolid_Type : Coverage::kNone_Type); 362244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 378cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // If we have perspective on the viewMatrix then we won't map on the CPU, nor will we map 388cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // the local rect on the cpu (in case the localMatrix also has perspective). 398cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // Otherwise, if we have a local rect, then we apply the localMatrix directly to the localRect 408cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // to generate vertex local coords 418cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt if (viewMatrix.hasPerspective()) { 428cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt LocalCoords localCoords(hasExplicitLocalCoords ? LocalCoords::kHasExplicit_Type : 438cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt LocalCoords::kUsePosition_Type, 448cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt localMatrix); 4506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, viewMatrix); 468cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt } else if (hasExplicitLocalCoords) { 472244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt LocalCoords localCoords(LocalCoords::kHasExplicit_Type); 4806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return GrDefaultGeoProcFactory::Make(color, coverage, localCoords, SkMatrix::I()); 492244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } else { 502244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt LocalCoords localCoords(LocalCoords::kUsePosition_Type, localMatrix); 5106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return GrDefaultGeoProcFactory::MakeForDeviceSpace(color, coverage, localCoords, 5206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman viewMatrix); 532244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 542244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt} 552244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 562244c27ea4db85df305fa09f664b7d75f637e7a9joshualittstatic void tesselate(intptr_t vertices, 572244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt size_t vertexStride, 582244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt GrColor color, 592244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt const SkMatrix& viewMatrix, 602244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt const SkRect& rect, 618cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt const GrQuad* localQuad) { 622244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkPoint* positions = reinterpret_cast<SkPoint*>(vertices); 632244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 642244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt positions->setRectFan(rect.fLeft, rect.fTop, 652244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt rect.fRight, rect.fBottom, vertexStride); 669c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 678cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt if (!viewMatrix.hasPerspective()) { 6808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon viewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerInstance); 698cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt } 708cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt 718cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // Setup local coords 722244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt // TODO we should only do this if local coords are being read 738cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt if (localQuad) { 742244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor); 7508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon for (int i = 0; i < kVertsPerInstance; i++) { 768cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt SkPoint* coords = reinterpret_cast<SkPoint*>(vertices + kLocalOffset + 778cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt i * vertexStride); 788cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt *coords = localQuad->point(i); 792244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 802244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 812244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 822244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static const int kColorOffset = sizeof(SkPoint); 832244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt GrColor* vertColor = reinterpret_cast<GrColor*>(vertices + kColorOffset); 842244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt for (int j = 0; j < 4; ++j) { 852244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt *vertColor = color; 862244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride); 872244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 882244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt} 892244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 9008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonclass NonAAFillRectBatch : public GrVertexBatch { 919c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualittpublic: 9208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon DEFINE_BATCH_CLASS_ID 9308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 949c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt struct Geometry { 959c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt SkMatrix fViewMatrix; 969c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt SkRect fRect; 978cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt GrQuad fLocalQuad; 989c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt GrColor fColor; 999c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt }; 1009c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 10108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static NonAAFillRectBatch* Create() { return new NonAAFillRectBatch; } 10208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 10308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const char* name() const override { return Name(); } 10408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 10508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkString dumpInfo() const override { 10608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkString str; 10708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.appendf("# batched: %d\n", fGeoData.count()); 10808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon for (int i = 0; i < fGeoData.count(); ++i) { 10908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.append(DumpInfo(fGeoData[i], i)); 11008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 11108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.append(INHERITED::dumpInfo()); 11208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return str; 11308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 11408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 11508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void computePipelineOptimizations(GrInitInvariantOutput* color, 11608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrInitInvariantOutput* coverage, 11708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrBatchToXPOverrides* overrides) const override { 11808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // When this is called on a batch, there is only one geometry bundle 11908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon color->setKnownFourComponents(fGeoData[0].fColor); 12008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon InitInvariantOutputCoverage(coverage); 12108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 12208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 12308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 12408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 12508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fOverrides = overrides; 12608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 12708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 12808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 12908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 13008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // After seeding, the client should call init() so the Batch can initialize itself 13108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void init() { 13208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& geo = fGeoData[0]; 13308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SetBounds(geo, &fBounds); 13408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 13508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 13608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void updateBoundsAfterAppend() { 13708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& geo = fGeoData.back(); 13808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon UpdateBoundsAfterAppend(geo, &fBounds); 13908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 14008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 14108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonprivate: 142bcf33d5c06f7560039797b6023f14466c75598edjoshualitt static const char* Name() { return "NonAAFillRectBatch"; } 1432244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 144783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips static SkString DumpInfo(const Geometry& geo, int index) { 145e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString str; 146783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", 147783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips index, 148e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips geo.fColor, 149e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect.fBottom); 150e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips return str; 151e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 152e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips 1532244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static bool CanCombine(const Geometry& mine, const Geometry& theirs, 154ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas const GrXPOverridesForBatch& overrides) { 1552244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt return true; 156ae41b3834301444cf27b8aa729b8ad36666bdc08joshualitt } 1579c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 15806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman static sk_sp<GrGeometryProcessor> MakeGP(const Geometry& geo, 15906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman const GrXPOverridesForBatch& overrides) { 16006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrGeometryProcessor> gp = make_gp(geo.fViewMatrix, overrides.readsCoverage(), true, 16106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman nullptr); 1629c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 1632244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkASSERT(gp->getVertexStride() == 1642244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr)); 1652244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt return gp; 1662244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 16787e4752fc1f7b079a65208e4b3543925a35c3e54joshualitt 1682244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo, 169ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas const GrXPOverridesForBatch& overrides) { 1708cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, &geo.fLocalQuad); 1712244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 17208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 17308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { 17408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon out->setKnownSingleComponent(0xff); 17508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 17608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 17708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { 17808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return rp->refQuadIndexBuffer(); 17908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 18008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 18108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void SetBounds(const Geometry& geo, SkRect* outBounds) { 18208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon geo.fViewMatrix.mapRect(outBounds, geo.fRect); 18308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 18408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 18508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { 18608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkRect bounds = geo.fRect; 18708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon geo.fViewMatrix.mapRect(&bounds); 18808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon outBounds->join(bounds); 18908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 19008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 19108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectBatch() : INHERITED(ClassID()) {} 19208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 19308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void onPrepareDraws(Target* target) const override { 19408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); 19508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!gp) { 19608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkDebugf("Couldn't create GrGeometryProcessor\n"); 19708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return; 19808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 19908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 20008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon size_t vertexStride = gp->getVertexStride(); 20108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon int instanceCount = fGeoData.count(); 20208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 20308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resourceProvider())); 20408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon InstancedHelper helper; 20508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, 20608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon indexBuffer, kVertsPerInstance, 20708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon kIndicesPerInstance, instanceCount); 20808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!vertices || !indexBuffer) { 20908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkDebugf("Could not allocate vertices\n"); 21008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return; 21108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 21208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 21308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon for (int i = 0; i < instanceCount; i++) { 21408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon intptr_t verts = reinterpret_cast<intptr_t>(vertices) + 21508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon i * kVertsPerInstance * vertexStride; 21608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon Tesselate(verts, vertexStride, fGeoData[i], fOverrides); 21708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 21808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon helper.recordDraw(target, gp.get()); 21908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 22008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 22108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& seedGeometry() const { return fGeoData[0]; } 22208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 22308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 22408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectBatch* that = t->cast<NonAAFillRectBatch>(); 22508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 22608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon that->bounds(), caps)) { 22708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return false; 22808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 22908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 23008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) { 23108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return false; 23208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 23308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 23408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // In the event of two batches, one who can tweak, one who cannot, we just fall back to 23508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // not tweaking 23608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { 23708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fOverrides = that->fOverrides; 23808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 23908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 24008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 24108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon this->joinBounds(that->bounds()); 24208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return true; 24308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 24408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 24508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrXPOverridesForBatch fOverrides; 24608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkSTArray<1, Geometry, true> fGeoData; 24708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 24808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon typedef GrVertexBatch INHERITED; 2492244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt}; 2509c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 2518cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt// We handle perspective in the local matrix or viewmatrix with special batches 25208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonclass NonAAFillRectPerspectiveBatch : public GrVertexBatch { 2532244c27ea4db85df305fa09f664b7d75f637e7a9joshualittpublic: 25408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon DEFINE_BATCH_CLASS_ID 25508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 2562244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt struct Geometry { 2572244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkMatrix fViewMatrix; 2582244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkMatrix fLocalMatrix; 2592244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkRect fRect; 2602244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkRect fLocalRect; 2612244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt GrColor fColor; 2628cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt bool fHasLocalMatrix; 2638cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt bool fHasLocalRect; 2642244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt }; 26587e4752fc1f7b079a65208e4b3543925a35c3e54joshualitt 26608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static NonAAFillRectPerspectiveBatch* Create() { return new NonAAFillRectPerspectiveBatch; } 26708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 26808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const char* name() const override { return Name(); } 26908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 27008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkString dumpInfo() const override { 27108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkString str; 27208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.appendf("# batched: %d\n", fGeoData.count()); 27308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon for (int i = 0; i < fGeoData.count(); ++i) { 27408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.append(DumpInfo(fGeoData[i], i)); 27508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 27608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon str.append(INHERITED::dumpInfo()); 27708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return str; 27808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 27908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 28008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void computePipelineOptimizations(GrInitInvariantOutput* color, 28108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrInitInvariantOutput* coverage, 28208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrBatchToXPOverrides* overrides) const override { 28308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // When this is called on a batch, there is only one geometry bundle 28408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon color->setKnownFourComponents(fGeoData[0].fColor); 28508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon InitInvariantOutputCoverage(coverage); 28608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 28708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 28808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 28908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 29008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fOverrides = overrides; 29108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 29208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 29308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 29408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 29508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // After seeding, the client should call init() so the Batch can initialize itself 29608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void init() { 29708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& geo = fGeoData[0]; 29808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SetBounds(geo, &fBounds); 29908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 30008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 30108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void updateBoundsAfterAppend() { 30208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& geo = fGeoData.back(); 30308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon UpdateBoundsAfterAppend(geo, &fBounds); 30408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 30508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 30608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomonprivate: 30708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static const char* Name() { return "NonAAFillRectPerspectiveBatch"; } 3089c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 309783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips static SkString DumpInfo(const Geometry& geo, int index) { 310e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString str; 311783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", 312783a4da10ba08187a5029d74cfa1507ac1b13307robertphillips index, 313e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips geo.fColor, 314e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips geo.fRect.fLeft, geo.fRect.fTop, geo.fRect.fRight, geo.fRect.fBottom); 315e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips return str; 316e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 317e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips 3182244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static bool CanCombine(const Geometry& mine, const Geometry& theirs, 319ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas const GrXPOverridesForBatch& overrides) { 3208cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt // We could batch across perspective vm changes if we really wanted to 3218cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt return mine.fViewMatrix.cheapEqualTo(theirs.fViewMatrix) && 3222120b6f2cc3070b16800bfb2ff05cf114c8e40b9joshualitt mine.fHasLocalRect == theirs.fHasLocalRect && 3238cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt (!mine.fHasLocalMatrix || mine.fLocalMatrix.cheapEqualTo(theirs.fLocalMatrix)); 3249c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt } 3259c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 32606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman static sk_sp<GrGeometryProcessor> MakeGP(const Geometry& geo, 32706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman const GrXPOverridesForBatch& overrides) { 32806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrGeometryProcessor> gp = make_gp(geo.fViewMatrix, overrides.readsCoverage(), 32906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman geo.fHasLocalRect, 33006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman geo.fHasLocalMatrix ? &geo.fLocalMatrix 33106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman : nullptr); 3328cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt 3338cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt SkASSERT(geo.fHasLocalRect ? 3348cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) : 3358cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); 3362244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt return gp; 3379c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt } 3389c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 3392244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt static void Tesselate(intptr_t vertices, size_t vertexStride, const Geometry& geo, 340ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas const GrXPOverridesForBatch& overrides) { 3418cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt if (geo.fHasLocalRect) { 3428cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt GrQuad quad(geo.fLocalRect); 3438cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, &quad); 3448cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt } else { 3458cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt tesselate(vertices, vertexStride, geo.fColor, geo.fViewMatrix, geo.fRect, nullptr); 3468cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt } 3472244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt } 348ae41b3834301444cf27b8aa729b8ad36666bdc08joshualitt 34908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void InitInvariantOutputCoverage(GrInitInvariantOutput* out) { 35008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon out->setKnownSingleComponent(0xff); 35108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 35208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 35308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static const GrBuffer* GetIndexBuffer(GrResourceProvider* rp) { 35408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return rp->refQuadIndexBuffer(); 35508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 35608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 35708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void SetBounds(const Geometry& geo, SkRect* outBounds) { 35808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon geo.fViewMatrix.mapRect(outBounds, geo.fRect); 35908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 36008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 36108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon static void UpdateBoundsAfterAppend(const Geometry& geo, SkRect* outBounds) { 36208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkRect bounds = geo.fRect; 36308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon geo.fViewMatrix.mapRect(&bounds); 36408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon outBounds->join(bounds); 36508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 36608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 36708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectPerspectiveBatch() : INHERITED(ClassID()) {} 36808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 36908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void onPrepareDraws(Target* target) const override { 37008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon sk_sp<GrGeometryProcessor> gp(MakeGP(this->seedGeometry(), fOverrides)); 37108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!gp) { 37208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkDebugf("Couldn't create GrGeometryProcessor\n"); 37308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return; 37408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 37508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 37608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon size_t vertexStride = gp->getVertexStride(); 37708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon int instanceCount = fGeoData.count(); 37808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 37908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkAutoTUnref<const GrBuffer> indexBuffer(GetIndexBuffer(target->resourceProvider())); 38008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon InstancedHelper helper; 38108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride, 38208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon indexBuffer, kVertsPerInstance, 38308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon kIndicesPerInstance, instanceCount); 38408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!vertices || !indexBuffer) { 38508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkDebugf("Could not allocate vertices\n"); 38608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return; 38708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 38808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 38908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon for (int i = 0; i < instanceCount; i++) { 39008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon intptr_t verts = reinterpret_cast<intptr_t>(vertices) + 39108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon i * kVertsPerInstance * vertexStride; 39208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon Tesselate(verts, vertexStride, fGeoData[i], fOverrides); 39308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 39408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon helper.recordDraw(target, gp.get()); 39508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 39608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 39708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const Geometry& seedGeometry() const { return fGeoData[0]; } 39808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 39908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 40008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectPerspectiveBatch* that = t->cast<NonAAFillRectPerspectiveBatch>(); 40108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 40208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon that->bounds(), caps)) { 40308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return false; 40408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 40508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 40608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (!CanCombine(this->seedGeometry(), that->seedGeometry(), fOverrides)) { 40708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return false; 40808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 40908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 41008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // In the event of two batches, one who can tweak, one who cannot, we just fall back to 41108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon // not tweaking 41208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (fOverrides.canTweakAlphaForCoverage() && !that->fOverrides.canTweakAlphaForCoverage()) { 41308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fOverrides = that->fOverrides; 41408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 41508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 41608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 41708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon this->joinBounds(that->bounds()); 41808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon return true; 41908d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon } 42008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 42108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon GrXPOverridesForBatch fOverrides; 42208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon SkSTArray<1, Geometry, true> fGeoData; 42308d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon 42408d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon typedef GrVertexBatch INHERITED; 42508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon}; 4262244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 42708d141534cb24a491edbf5db31cdc7b966ec8d72bsalomoninline static void append_to_batch(NonAAFillRectBatch* batch, GrColor color, 428aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix& viewMatrix, const SkRect& rect, 429aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect* localRect, const SkMatrix* localMatrix) { 4303566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt SkASSERT(!viewMatrix.hasPerspective() && (!localMatrix || !localMatrix->hasPerspective())); 43108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectBatch::Geometry& geo = batch->geoData()->push_back(); 4323566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt 4333566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fColor = color; 4343566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fViewMatrix = viewMatrix; 4353566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fRect = rect; 4363566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt 4373566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt if (localRect && localMatrix) { 4383566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalQuad.setFromMappedRect(*localRect, *localMatrix); 4393566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt } else if (localRect) { 4403566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalQuad.set(*localRect); 4413566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt } else if (localMatrix) { 4423566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalQuad.setFromMappedRect(rect, *localMatrix); 44387e4752fc1f7b079a65208e4b3543925a35c3e54joshualitt } else { 4443566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalQuad.set(rect); 4453566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt } 4463566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt} 4478cce8f139e4b91783722f11ccb6ac9bbdf8327e7joshualitt 44808d141534cb24a491edbf5db31cdc7b966ec8d72bsalomoninline static void append_to_batch(NonAAFillRectPerspectiveBatch* batch, GrColor color, 449aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix& viewMatrix, const SkRect& rect, 450aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect* localRect, const SkMatrix* localMatrix) { 4513566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt SkASSERT(viewMatrix.hasPerspective() || (localMatrix && localMatrix->hasPerspective())); 45208d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->push_back(); 4533566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt 4543566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fColor = color; 4553566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fViewMatrix = viewMatrix; 4563566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fRect = rect; 4573566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fHasLocalRect = SkToBool(localRect); 4583566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fHasLocalMatrix = SkToBool(localMatrix); 4593566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt if (localMatrix) { 4603566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalMatrix = *localMatrix; 46187e4752fc1f7b079a65208e4b3543925a35c3e54joshualitt } 4623566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt if (localRect) { 4633566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt geo.fLocalRect = *localRect; 4643566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt } 4653566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt 466aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt} 467aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 468aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualittnamespace GrNonAAFillRectBatch { 469aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 470aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualittGrDrawBatch* Create(GrColor color, 471aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix& viewMatrix, 472aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect& rect, 473aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect* localRect, 474aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix* localMatrix) { 47508d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectBatch* batch = NonAAFillRectBatch::Create(); 476aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); 477aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt batch->init(); 478aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt return batch; 479aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt} 480aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 481aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualittGrDrawBatch* CreateWithPerspective(GrColor color, 482aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix& viewMatrix, 483aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect& rect, 484aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect* localRect, 485aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix* localMatrix) { 48608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectPerspectiveBatch* batch = NonAAFillRectPerspectiveBatch::Create(); 487aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); 4883566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt batch->init(); 4893566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt return batch; 4909c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt} 4913566d44d852b2fc1773e41e80c0c19610aa6d43bjoshualitt 492aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualittbool Append(GrBatch* origBatch, 493aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt GrColor color, 494aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix& viewMatrix, 495aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect& rect, 496aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkRect* localRect, 497aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt const SkMatrix* localMatrix) { 498aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt bool usePerspective = viewMatrix.hasPerspective() || 499aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt (localMatrix && localMatrix->hasPerspective()); 500aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 50108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon if (usePerspective && origBatch->classID() != NonAAFillRectPerspectiveBatch::ClassID()) { 502aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt return false; 503aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt } 504aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 505aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt if (!usePerspective) { 50608d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectBatch* batch = origBatch->cast<NonAAFillRectBatch>(); 507aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); 508aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt batch->updateBoundsAfterAppend(); 509aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt } else { 51008d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon NonAAFillRectPerspectiveBatch* batch = origBatch->cast<NonAAFillRectPerspectiveBatch>(); 51108d141534cb24a491edbf5db31cdc7b966ec8d72bsalomon const NonAAFillRectPerspectiveBatch::Geometry& geo = batch->geoData()->back(); 512aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 513aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt if (!geo.fViewMatrix.cheapEqualTo(viewMatrix) || 514aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt geo.fHasLocalRect != SkToBool(localRect) || 515aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt geo.fHasLocalMatrix != SkToBool(localMatrix) || 516aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt (geo.fHasLocalMatrix && !geo.fLocalMatrix.cheapEqualTo(*localMatrix))) { 517aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt return false; 518aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt } 519aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 520aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt append_to_batch(batch, color, viewMatrix, rect, localRect, localMatrix); 521aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt batch->updateBoundsAfterAppend(); 522aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt } 523aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 524aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt return true; 525aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt} 526aa37a96d554c5be7907ce04ee1ef843d0521eafbjoshualitt 5279c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt}; 5289c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 5299c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 5309c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 5319c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#ifdef GR_TEST_UTILS 5329c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 5339c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#include "GrBatchTest.h" 5349c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 535abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(RectBatch) { 5362244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt GrColor color = GrRandomColor(random); 5372244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkRect rect = GrTest::TestRect(random); 5382244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkRect localRect = GrTest::TestRect(random); 5392244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random); 5402244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt SkMatrix localMatrix = GrTest::TestMatrix(random); 5412244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt 5422244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt bool hasLocalRect = random->nextBool(); 5432244c27ea4db85df305fa09f664b7d75f637e7a9joshualitt bool hasLocalMatrix = random->nextBool(); 544bcf33d5c06f7560039797b6023f14466c75598edjoshualitt return GrNonAAFillRectBatch::Create(color, viewMatrix, rect, 545bcf33d5c06f7560039797b6023f14466c75598edjoshualitt hasLocalRect ? &localRect : nullptr, 546bcf33d5c06f7560039797b6023f14466c75598edjoshualitt hasLocalMatrix ? &localMatrix : nullptr); 5479c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt} 5489c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt 5499c80b5ff592caf1c18b43e98c85bc8340b3ac531joshualitt#endif 550