GrPipelineBuilder.cpp revision 4d8da81562852e0ff7e18b66ee1cebd50ad81ee8
1af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com/*
28dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel * Copyright 2015 Google Inc.
3af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com *
4af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com * found in the LICENSE file.
6af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com */
7af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
88dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel#include "GrPipelineBuilder.h"
93658f382cc129e463d7f40a7e68214d04d50fe14egdaniel
10b1cff03325c42bb1cd87204d9b0dd3d6b9678d3eegdaniel#include "GrBlend.h"
113658f382cc129e463d7f40a7e68214d04d50fe14egdaniel#include "GrPaint.h"
128dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel#include "GrPipeline.h"
13b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel#include "GrProcOptInfo.h"
14378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "GrXferProcessor.h"
15378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel#include "effects/GrPorterDuffXferProcessor.h"
163658f382cc129e463d7f40a7e68214d04d50fe14egdaniel
178dd688b7569df569a672a8a67b2db86a9d376cfcegdanielGrPipelineBuilder::GrPipelineBuilder()
182fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    : fFlagBits(0x0)
192fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    , fDrawFace(kBoth_DrawFace)
202fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    , fColorProcInfoValid(false)
212fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    , fCoverageProcInfoValid(false)
222fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    , fColorCache(GrColor_ILLEGAL)
234d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    , fCoverageCache(GrColor_ILLEGAL) {
242fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
2589af44a0f1323dc136b238c00ccf143e15abb243egdaniel}
2689af44a0f1323dc136b238c00ccf143e15abb243egdaniel
278dd688b7569df569a672a8a67b2db86a9d376cfcegdanielGrPipelineBuilder& GrPipelineBuilder::operator=(const GrPipelineBuilder& that) {
28ae59b77612c42ff6b793dc33e3d115e6a5db34ccbsalomon    fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
298f7273399466c95c0c86b099de438d6ef1a15c88bsalomon    fFlagBits = that.fFlagBits;
308f7273399466c95c0c86b099de438d6ef1a15c88bsalomon    fStencilSettings = that.fStencilSettings;
318f7273399466c95c0c86b099de438d6ef1a15c88bsalomon    fDrawFace = that.fDrawFace;
32378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    fXPFactory.reset(SkRef(that.getXPFactory()));
338cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel    fColorStages = that.fColorStages;
348cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel    fCoverageStages = that.fCoverageStages;
358f7273399466c95c0c86b099de438d6ef1a15c88bsalomon
36b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    fColorProcInfoValid = that.fColorProcInfoValid;
37b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    fCoverageProcInfoValid = that.fCoverageProcInfoValid;
38f364b61dd86aa2a9d8cc7b01d9e78e066bd88334joshualitt    fColorCache = that.fColorCache;
39f364b61dd86aa2a9d8cc7b01d9e78e066bd88334joshualitt    fCoverageCache = that.fCoverageCache;
40b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    if (fColorProcInfoValid) {
41b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        fColorProcInfo = that.fColorProcInfo;
42b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    }
43b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    if (fCoverageProcInfoValid) {
44b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        fCoverageProcInfo = that.fCoverageProcInfo;
45b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    }
468f7273399466c95c0c86b099de438d6ef1a15c88bsalomon    return *this;
478f7273399466c95c0c86b099de438d6ef1a15c88bsalomon}
488f7273399466c95c0c86b099de438d6ef1a15c88bsalomon
498dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt) {
5056995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
51eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
528cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel    fColorStages.reset();
538cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel    fCoverageStages.reset();
54eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
5542dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org    for (int i = 0; i < paint.numColorStages(); ++i) {
568cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel        fColorStages.push_back(paint.getColorStage(i));
57af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
58af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
5942dacab4e7366d9f53989558cc8d045c3d065bcdcommit-bot@chromium.org    for (int i = 0; i < paint.numCoverageStages(); ++i) {
608cbf3d5b17e5f95ed992c019fb6165f079c385adegdaniel        fCoverageStages.push_back(paint.getCoverageStage(i));
61af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
62af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
63378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel    fXPFactory.reset(SkRef(paint.getXPFactory()));
64378092f3d10b1dd62967f419c35cfefec7c10ee7egdaniel
65bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org    this->setRenderTarget(rt);
66bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org
67bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org    // These have no equivalent in GrPaint, set them to defaults
682ed5ef84a5609089ad9d8a8f3a52bf77e76476dbbsalomon    fDrawFace = kBoth_DrawFace;
692ed5ef84a5609089ad9d8a8f3a52bf77e76476dbbsalomon    fStencilSettings.setDisabled();
7004ddf89627077ea8f2b447e7cd5e902956341a32bsalomon    fFlagBits = 0;
71bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org
7221c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.com    // Enable the clip bit
738dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    this->enableState(GrPipelineBuilder::kClip_StateBit);
7421c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.com
758dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    this->setState(GrPipelineBuilder::kDither_StateBit, paint.isDither());
768dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    this->setState(GrPipelineBuilder::kHWAntialias_StateBit, paint.isAntiAlias());
77af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
78b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    fColorProcInfoValid = false;
79b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    fCoverageProcInfoValid = false;
802e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt
812e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    fColorCache = GrColor_ILLEGAL;
822e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    fCoverageCache = GrColor_ILLEGAL;
83af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com}
845b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
855b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com////////////////////////////////////////////////////////////////////////////////
865b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
878dd688b7569df569a672a8a67b2db86a9d376cfcegdanielbool GrPipelineBuilder::canUseFracCoveragePrimProc(GrColor color,
888dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                                   const GrDrawTargetCaps& caps) const {
8962c447d3a556e3042cdf5d23b3e2a618eaa3c100bsalomon    if (caps.dualSourceBlendingSupport()) {
9062c447d3a556e3042cdf5d23b3e2a618eaa3c100bsalomon        return true;
9162c447d3a556e3042cdf5d23b3e2a618eaa3c100bsalomon    }
929513143efa734bef0c1a0c7f945022572dbc8518egdaniel
932e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    this->calcColorInvariantOutput(color);
942e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt
952e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    // The coverage isn't actually white, its unknown, but this will produce the same effect
962e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    // TODO we want to cache the result of this call, but we can probably clean up the interface
972e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    // so we don't have to pass in a seemingly known coverage
982e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    this->calcCoverageInvariantOutput(GrColor_WHITE);
992fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    return this->getXPFactory()->canApplyCoverage(fColorProcInfo, fCoverageProcInfo);
10089af44a0f1323dc136b238c00ccf143e15abb243egdaniel}
10189af44a0f1323dc136b238c00ccf143e15abb243egdaniel
10221aed57023bad4b04076c59e37097c7563efc028egdaniel//////////////////////////////////////////////////////////////////////////////s
103d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
1048dd688b7569df569a672a8a67b2db86a9d376cfcegdanielbool GrPipelineBuilder::willEffectReadDstColor() const {
1052fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    return this->getXPFactory()->willReadDst();
10689af44a0f1323dc136b238c00ccf143e15abb243egdaniel}
10789af44a0f1323dc136b238c00ccf143e15abb243egdaniel
1088dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::AutoRestoreEffects::set(GrPipelineBuilder* pipelineBuilder) {
1098dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    if (fPipelineBuilder) {
1108dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        int m = fPipelineBuilder->numColorStages() - fColorEffectCnt;
11121aed57023bad4b04076c59e37097c7563efc028egdaniel        SkASSERT(m >= 0);
1128dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        fPipelineBuilder->fColorStages.pop_back_n(m);
113d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
1148dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        int n = fPipelineBuilder->numCoverageStages() - fCoverageEffectCnt;
11521aed57023bad4b04076c59e37097c7563efc028egdaniel        SkASSERT(n >= 0);
1168dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        fPipelineBuilder->fCoverageStages.pop_back_n(n);
117b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        if (m + n > 0) {
1188dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel            fPipelineBuilder->fColorProcInfoValid = false;
1198dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel            fPipelineBuilder->fCoverageProcInfoValid = false;
120b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        }
1218dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
12221aed57023bad4b04076c59e37097c7563efc028egdaniel    }
1238dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    fPipelineBuilder = pipelineBuilder;
1248dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    if (NULL != pipelineBuilder) {
1258dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        fColorEffectCnt = pipelineBuilder->numColorStages();
1268dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        fCoverageEffectCnt = pipelineBuilder->numCoverageStages();
1278dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
128d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com    }
129d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}
130d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
131cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com////////////////////////////////////////////////////////////////////////////////
132cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
13389af44a0f1323dc136b238c00ccf143e15abb243egdaniel// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
13489af44a0f1323dc136b238c00ccf143e15abb243egdaniel// others will blend incorrectly.
1358dd688b7569df569a672a8a67b2db86a9d376cfcegdanielbool GrPipelineBuilder::canTweakAlphaForCoverage() const {
1362fdeda04988867625bb9bc2f7f6037406a0a98ecjoshualitt    return this->getXPFactory()->canTweakAlphaForCoverage();
13789af44a0f1323dc136b238c00ccf143e15abb243egdaniel}
13889af44a0f1323dc136b238c00ccf143e15abb243egdaniel
13989af44a0f1323dc136b238c00ccf143e15abb243egdaniel////////////////////////////////////////////////////////////////////////////////
14089af44a0f1323dc136b238c00ccf143e15abb243egdaniel
1418dd688b7569df569a672a8a67b2db86a9d376cfcegdanielGrPipelineBuilder::~GrPipelineBuilder() {
142170f90b4576f291879371ecd6ae4bc2b1d85c64aegdaniel    SkASSERT(0 == fBlockEffectRemovalCnt);
143170f90b4576f291879371ecd6ae4bc2b1d85c64aegdaniel}
144170f90b4576f291879371ecd6ae4bc2b1d85c64aegdaniel
14589af44a0f1323dc136b238c00ccf143e15abb243egdaniel////////////////////////////////////////////////////////////////////////////////
14689af44a0f1323dc136b238c00ccf143e15abb243egdaniel
1478dd688b7569df569a672a8a67b2db86a9d376cfcegdanielbool GrPipelineBuilder::willBlendWithDst(const GrPrimitiveProcessor* pp) const {
14856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    this->calcColorInvariantOutput(pp);
14956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt    this->calcCoverageInvariantOutput(pp);
1509e4ecdc9f86724dcce23dc7546e2f295b901407begdaniel
1519e4ecdc9f86724dcce23dc7546e2f295b901407begdaniel    GrXPFactory::InvariantOutput output;
152080e673b10ac607305f140ddb245e140ccde40c6egdaniel    fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
1539e4ecdc9f86724dcce23dc7546e2f295b901407begdaniel    return output.fWillBlendWithDst;
15456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt}
15556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt
1568dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::calcColorInvariantOutput(const GrPrimitiveProcessor* pp) const {
1574d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fColorProcInfo.calcColorWithPrimProc(pp, fColorStages.begin(), this->numColorStages());
1584d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fColorProcInfoValid = false;
1594d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
16089af44a0f1323dc136b238c00ccf143e15abb243egdaniel}
16189af44a0f1323dc136b238c00ccf143e15abb243egdaniel
1628dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::calcCoverageInvariantOutput(const GrPrimitiveProcessor* pp) const {
1634d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fCoverageProcInfo.calcCoverageWithPrimProc(pp, fCoverageStages.begin(),
1644d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt                                               this->numCoverageStages());
1654d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fCoverageProcInfoValid = false;
166d5a7db4a867c7e6ccf8451a053d987b470099198joshualitt}
167d5a7db4a867c7e6ccf8451a053d987b470099198joshualitt
1684d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittvoid GrPipelineBuilder::calcColorInvariantOutput(const GrBatch* batch) const {
1694d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fColorProcInfo.calcColorWithBatch(batch, fColorStages.begin(), this->numColorStages());
1704d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fColorProcInfoValid = false;
1714d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt}
1724d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
1734d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualittvoid GrPipelineBuilder::calcCoverageInvariantOutput(const GrBatch* batch) const {
1744d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fCoverageProcInfo.calcCoverageWithBatch(batch, fCoverageStages.begin(),
1754d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt                                            this->numCoverageStages());
1764d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt    fCoverageProcInfoValid = false;
1774d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt}
1784d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
1794d8da81562852e0ff7e18b66ee1cebd50ad81ee8joshualitt
1808dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::calcColorInvariantOutput(GrColor color) const {
1812e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    if (!fColorProcInfoValid || color != fColorCache) {
18256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
18356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color,
18456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                             flags, false);
185b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        fColorProcInfoValid = true;
1862e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        fColorCache = color;
187b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    }
188b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel}
189b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel
1908dd688b7569df569a672a8a67b2db86a9d376cfcegdanielvoid GrPipelineBuilder::calcCoverageInvariantOutput(GrColor coverage) const {
1912e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    if (!fCoverageProcInfoValid || coverage != fCoverageCache) {
19256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        GrColorComponentFlags flags = kRGBA_GrColorComponentFlags;
19356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt        fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(),
19456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                this->numCoverageStages(), coverage, flags,
19556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                true);
196b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel        fCoverageProcInfoValid = true;
1972e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt        fCoverageCache = coverage;
198b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel    }
199b6cbc38702dc4a1540a17181cbdab71060c92ce7egdaniel}
200