1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrPipelineBuilder.h"
9
10#include "GrBlend.h"
11#include "GrPaint.h"
12#include "GrPipeline.h"
13#include "GrProcOptInfo.h"
14#include "GrXferProcessor.h"
15#include "batches/GrBatch.h"
16#include "effects/GrPorterDuffXferProcessor.h"
17
18GrPipelineBuilder::GrPipelineBuilder()
19    : fFlags(0x0), fDrawFace(kBoth_DrawFace) {
20    SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
21}
22
23GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip) {
24    SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
25
26    for (int i = 0; i < paint.numColorFragmentProcessors(); ++i) {
27        fColorFragmentProcessors.push_back(SkRef(paint.getColorFragmentProcessor(i)));
28    }
29
30    for (int i = 0; i < paint.numCoverageFragmentProcessors(); ++i) {
31        fCoverageFragmentProcessors.push_back(SkRef(paint.getCoverageFragmentProcessor(i)));
32    }
33
34    fXPFactory.reset(SkSafeRef(paint.getXPFactory()));
35
36    this->setRenderTarget(rt);
37
38    // These have no equivalent in GrPaint, set them to defaults
39    fDrawFace = kBoth_DrawFace;
40    fStencilSettings.setDisabled();
41    fFlags = 0;
42
43    fClip = clip;
44
45    this->setState(GrPipelineBuilder::kHWAntialias_Flag,
46                   rt->isUnifiedMultisampled() && paint.isAntiAlias());
47}
48
49//////////////////////////////////////////////////////////////////////////////s
50
51bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
52                                             const GrPipelineOptimizations& optimizations) const {
53    if (this->getXPFactory()) {
54        return this->getXPFactory()->willNeedDstTexture(caps, optimizations,
55                                                        this->hasMixedSamples());
56    }
57    return GrPorterDuffXPFactory::SrcOverWillNeedDstTexture(caps, optimizations,
58                                                            this->hasMixedSamples());
59}
60
61void GrPipelineBuilder::AutoRestoreFragmentProcessorState::set(
62                                                         const GrPipelineBuilder* pipelineBuilder) {
63    if (fPipelineBuilder) {
64        int m = fPipelineBuilder->numColorFragmentProcessors() - fColorEffectCnt;
65        SkASSERT(m >= 0);
66        for (int i = 0; i < m; ++i) {
67            fPipelineBuilder->fColorFragmentProcessors.fromBack(i)->unref();
68        }
69        fPipelineBuilder->fColorFragmentProcessors.pop_back_n(m);
70
71        int n = fPipelineBuilder->numCoverageFragmentProcessors() - fCoverageEffectCnt;
72        SkASSERT(n >= 0);
73        for (int i = 0; i < n; ++i) {
74            fPipelineBuilder->fCoverageFragmentProcessors.fromBack(i)->unref();
75        }
76        fPipelineBuilder->fCoverageFragmentProcessors.pop_back_n(n);
77        SkDEBUGCODE(--fPipelineBuilder->fBlockEffectRemovalCnt;)
78    }
79    fPipelineBuilder = const_cast<GrPipelineBuilder*>(pipelineBuilder);
80    if (nullptr != pipelineBuilder) {
81        fColorEffectCnt = pipelineBuilder->numColorFragmentProcessors();
82        fCoverageEffectCnt = pipelineBuilder->numCoverageFragmentProcessors();
83        SkDEBUGCODE(++pipelineBuilder->fBlockEffectRemovalCnt;)
84    }
85}
86
87////////////////////////////////////////////////////////////////////////////////
88
89GrPipelineBuilder::~GrPipelineBuilder() {
90    SkASSERT(0 == fBlockEffectRemovalCnt);
91    for (int i = 0; i < fColorFragmentProcessors.count(); ++i) {
92        fColorFragmentProcessors[i]->unref();
93    }
94    for (int i = 0; i < fCoverageFragmentProcessors.count(); ++i) {
95        fCoverageFragmentProcessors[i]->unref();
96    }
97}
98