GrRegionOp.cpp revision 8c852be264d003b2e610c5b8634bc0f81c46bbba
1cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett/* 2cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett * Copyright 2016 Google Inc. 3cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett * 4cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett * Use of this source code is governed by a BSD-style license that can be 5cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett * found in the LICENSE file. 6cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett */ 7cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 8fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon#include "GrRegionOp.h" 9cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 10dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "GrDefaultGeoProcFactory.h" 11dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon#include "GrMeshDrawOp.h" 12742e31de1599f3902810aecdf2e2e3eed3b40a09Brian Salomon#include "GrOpFlushState.h" 13cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett#include "GrResourceProvider.h" 14cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett#include "SkMatrixPriv.h" 15cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett#include "SkRegion.h" 16cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 17cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarettstatic const int kVertsPerInstance = 4; 18cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarettstatic const int kIndicesPerInstance = 6; 19cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 208c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomonstatic sk_sp<GrGeometryProcessor> make_gp(const SkMatrix& viewMatrix) { 21cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett using namespace GrDefaultGeoProcFactory; 228c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon return GrDefaultGeoProcFactory::Make(Color::kAttribute_Type, Coverage::kSolid_Type, 238c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon LocalCoords::kUsePosition_Type, viewMatrix); 24cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett} 25cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 26febb22469999b928850182ebc57bfd6fbd7402d6msarettstatic void tesselate_region(intptr_t vertices, 27fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon size_t vertexStride, 28fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon GrColor color, 29fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon const SkRegion& region) { 30cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkRegion::Iterator iter(region); 31cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 32cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett intptr_t verts = vertices; 33cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett while (!iter.done()) { 34febb22469999b928850182ebc57bfd6fbd7402d6msarett SkRect rect = SkRect::Make(iter.rect()); 35fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon SkPoint* position = (SkPoint*)verts; 36febb22469999b928850182ebc57bfd6fbd7402d6msarett position->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vertexStride); 37cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 38cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett static const int kColorOffset = sizeof(SkPoint); 39cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett GrColor* vertColor = reinterpret_cast<GrColor*>(verts + kColorOffset); 40cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett for (int i = 0; i < kVertsPerInstance; i++) { 41cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett *vertColor = color; 42fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon vertColor = (GrColor*)((intptr_t)vertColor + vertexStride); 43cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 44cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 45cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett verts += vertexStride * kVertsPerInstance; 46cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett iter.next(); 47cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 48cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett} 49cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 50fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomonclass RegionOp final : public GrMeshDrawOp { 51cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarettpublic: 5225a880960a9a689a745a01071ecba3fe494b5940Brian Salomon DEFINE_OP_CLASS_ID 53cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 54fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon RegionOp(GrColor color, const SkMatrix& viewMatrix, const SkRegion& region) 55fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon : INHERITED(ClassID()), fViewMatrix(viewMatrix) { 56cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett RegionInfo& info = fRegions.push_back(); 57cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett info.fColor = color; 58cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett info.fRegion = region; 59cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 60cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkRect bounds = SkRect::Make(region.getBounds()); 61cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett this->setTransformedBounds(bounds, viewMatrix, HasAABloat::kNo, IsZeroArea::kNo); 62cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 63cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 64fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon const char* name() const override { return "GrRegionOp"; } 65cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 66cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkString dumpInfo() const override { 67cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkString str; 6853e4c3c0da40b58638d05e0f753ab6d450b961f5Brian Salomon str.appendf("# combined: %d\n", fRegions.count()); 69cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett for (int i = 0; i < fRegions.count(); ++i) { 70cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett const RegionInfo& info = fRegions[i]; 71fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon str.appendf("%d: Color: 0x%08x, Region with %d rects\n", i, info.fColor, 72fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon info.fRegion.computeRegionComplexity()); 73cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 747c3e7180948766321c51d165737555e78910de51Brian Salomon str.append(DumpPipelineInfo(*this->pipeline())); 75cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett str.append(INHERITED::dumpInfo()); 76cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett return str; 77cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 78cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 7992aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomonprivate: 8092aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon void getPipelineAnalysisInput(GrPipelineAnalysisDrawOpInput* input) const override { 8192aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon input->pipelineColorInput()->setKnownFourComponents(fRegions[0].fColor); 8292aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon input->pipelineCoverageInput()->setKnownSingleComponent(0xff); 83cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 84cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 8592aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon void applyPipelineOptimizations(const GrPipelineOptimizations& optimizations) override { 8692aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon optimizations.getOverrideColorIfSet(&fRegions[0].fColor); 8792aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon fOptimizations = optimizations; 88cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 89cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 90cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett void onPrepareDraws(Target* target) const override { 918c852be264d003b2e610c5b8634bc0f81c46bbbaBrian Salomon sk_sp<GrGeometryProcessor> gp = make_gp(fViewMatrix); 92cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett if (!gp) { 93cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkDebugf("Couldn't create GrGeometryProcessor\n"); 94cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett return; 95cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 96febb22469999b928850182ebc57bfd6fbd7402d6msarett SkASSERT(gp->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); 97cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 98cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett int numRegions = fRegions.count(); 99cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett int numRects = 0; 100cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett for (int i = 0; i < numRegions; i++) { 101cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett numRects += fRegions[i].fRegion.computeRegionComplexity(); 102cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 103cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 104cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett size_t vertexStride = gp->getVertexStride(); 105144caf55ffc692bcda77703a73bb9a894f7d024fHal Canary sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer()); 106cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett InstancedHelper helper; 107fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon void* vertices = 108fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(), 109fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon kVertsPerInstance, kIndicesPerInstance, numRects); 110cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett if (!vertices || !indexBuffer) { 111cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkDebugf("Could not allocate vertices\n"); 112cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett return; 113cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 114cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 115cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett intptr_t verts = reinterpret_cast<intptr_t>(vertices); 116cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett for (int i = 0; i < numRegions; i++) { 117febb22469999b928850182ebc57bfd6fbd7402d6msarett tesselate_region(verts, vertexStride, fRegions[i].fColor, fRegions[i].fRegion); 118febb22469999b928850182ebc57bfd6fbd7402d6msarett int numRectsInRegion = fRegions[i].fRegion.computeRegionComplexity(); 119cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett verts += numRectsInRegion * kVertsPerInstance * vertexStride; 120cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 121cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett helper.recordDraw(target, gp.get()); 122cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 123cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 12425a880960a9a689a745a01071ecba3fe494b5940Brian Salomon bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override { 125fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon RegionOp* that = t->cast<RegionOp>(); 126cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 127cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett that->bounds(), caps)) { 128cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett return false; 129cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 130cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 131febb22469999b928850182ebc57bfd6fbd7402d6msarett if (fViewMatrix != that->fViewMatrix) { 132febb22469999b928850182ebc57bfd6fbd7402d6msarett return false; 133febb22469999b928850182ebc57bfd6fbd7402d6msarett } 134febb22469999b928850182ebc57bfd6fbd7402d6msarett 135cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett fRegions.push_back_n(that->fRegions.count(), that->fRegions.begin()); 136cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett this->joinBounds(*that); 137cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett return true; 138cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett } 139cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 140cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett struct RegionInfo { 141cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett GrColor fColor; 142cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkRegion fRegion; 143cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett }; 144cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 145febb22469999b928850182ebc57bfd6fbd7402d6msarett SkMatrix fViewMatrix; 14692aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon GrPipelineOptimizations fOptimizations; 147cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett SkSTArray<1, RegionInfo, true> fRegions; 148cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 149dad2923b8ec9270d810c1e8e76da8e6768d8f9ddBrian Salomon typedef GrMeshDrawOp INHERITED; 150cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett}; 151cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 152fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomonnamespace GrRegionOp { 153cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett 154f8334781914363caf537f22f012fcd5c03c60dadBrian Salomonstd::unique_ptr<GrDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, const SkRegion& region) { 155f8334781914363caf537f22f012fcd5c03c60dadBrian Salomon return std::unique_ptr<GrDrawOp>(new RegionOp(color, viewMatrix, region)); 156fc527d27641bb693a0a7703ba9d35100f7500fd7Brian Salomon} 157cc319b95a58ae15e88c3c028b8726e7cab9121ffmsarett} 158