1/*
2 * Copyright 2012 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#ifndef GrProcessor_DEFINED
9#define GrProcessor_DEFINED
10
11#include "../private/SkAtomics.h"
12#include "GrBuffer.h"
13#include "GrColor.h"
14#include "GrGpuResourceRef.h"
15#include "GrProcessorUnitTest.h"
16#include "GrProgramElement.h"
17#include "GrSamplerState.h"
18#include "GrShaderVar.h"
19#include "GrSurfaceProxyPriv.h"
20#include "GrSurfaceProxyRef.h"
21#include "GrTextureProxy.h"
22#include "SkMath.h"
23#include "SkString.h"
24
25class GrContext;
26class GrCoordTransform;
27class GrInvariantOutput;
28class GrResourceProvider;
29
30/**
31 * Used by processors to build their keys. It incorporates each per-processor key into a larger
32 * shader key.
33 */
34class GrProcessorKeyBuilder {
35public:
36    GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) {
37        SkASSERT(0 == fData->count() % sizeof(uint32_t));
38    }
39
40    void add32(uint32_t v) {
41        ++fCount;
42        fData->push_back_n(4, reinterpret_cast<uint8_t*>(&v));
43    }
44
45    /** Inserts count uint32_ts into the key. The returned pointer is only valid until the next
46        add*() call. */
47    uint32_t* SK_WARN_UNUSED_RESULT add32n(int count) {
48        SkASSERT(count > 0);
49        fCount += count;
50        return reinterpret_cast<uint32_t*>(fData->push_back_n(4 * count));
51    }
52
53    size_t size() const { return sizeof(uint32_t) * fCount; }
54
55private:
56    SkTArray<uint8_t, true>* fData; // unowned ptr to the larger key.
57    int fCount;                     // number of uint32_ts added to fData by the processor.
58};
59
60/** Provides custom shader code to the Ganesh shading pipeline. GrProcessor objects *must* be
61    immutable: after being constructed, their fields may not change.
62
63    Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an
64    processor must reach 0 before the thread terminates and the pool is destroyed.
65 */
66class GrProcessor {
67public:
68    enum ClassID {
69        kBigKeyProcessor_ClassID,
70        kBlockInputFragmentProcessor_ClassID,
71        kButtCapStrokedCircleGeometryProcessor_ClassID,
72        kCircleGeometryProcessor_ClassID,
73        kCircularRRectEffect_ClassID,
74        kColorMatrixEffect_ClassID,
75        kColorTableEffect_ClassID,
76        kComposeOneFragmentProcessor_ClassID,
77        kComposeTwoFragmentProcessor_ClassID,
78        kCoverageSetOpXP_ClassID,
79        kCustomXP_ClassID,
80        kDashingCircleEffect_ClassID,
81        kDashingLineEffect_ClassID,
82        kDefaultGeoProc_ClassID,
83        kDIEllipseGeometryProcessor_ClassID,
84        kDisableColorXP_ClassID,
85        kTwoPointConicalEffect_ClassID,
86        kEllipseGeometryProcessor_ClassID,
87        kEllipticalRRectEffect_ClassID,
88        kGP_ClassID,
89        kGrAARectEffect_ClassID,
90        kGrAlphaThresholdFragmentProcessor_ClassID,
91        kGrArithmeticFP_ClassID,
92        kGrBicubicEffect_ClassID,
93        kGrBitmapTextGeoProc_ClassID,
94        kGrBlurredEdgeFragmentProcessor_ClassID,
95        kGrCCClipProcessor_ClassID,
96        kGrCCCoverageProcessor_ClassID,
97        kGrCCPathProcessor_ClassID,
98        kGrCircleBlurFragmentProcessor_ClassID,
99        kGrCircleEffect_ClassID,
100        kGrColorSpaceXformEffect_ClassID,
101        kGrConfigConversionEffect_ClassID,
102        kGrConicEffect_ClassID,
103        kGrConstColorProcessor_ClassID,
104        kGrConvexPolyEffect_ClassID,
105        kGrCubicEffect_ClassID,
106        kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID,
107        kGrDiffuseLightingEffect_ClassID,
108        kGrDisplacementMapEffect_ClassID,
109        kGrDistanceFieldA8TextGeoProc_ClassID,
110        kGrDistanceFieldLCDTextGeoProc_ClassID,
111        kGrDistanceFieldPathGeoProc_ClassID,
112        kGrDitherEffect_ClassID,
113        kGrEllipseEffect_ClassID,
114        kGrGaussianConvolutionFragmentProcessor_ClassID,
115        kGrImprovedPerlinNoiseEffect_ClassID,
116        kGrLightingEffect_ClassID,
117        kGrLinearGradient_ClassID,
118        kGrLumaColorFilterEffect_ClassID,
119        kGrMagnifierEffect_ClassID,
120        kGrMatrixConvolutionEffect_ClassID,
121        kGrMeshTestProcessor_ClassID,
122        kGrMorphologyEffect_ClassID,
123        kGrNonlinearColorSpaceXformEffect_ClassID,
124        kGrOverdrawFragmentProcessor_ClassID,
125        kGrPathProcessor_ClassID,
126        kGrPerlinNoise2Effect_ClassID,
127        kGrPipelineDynamicStateTestProcessor_ClassID,
128        kGrPremulInputFragmentProcessor_ClassID,
129        kGrQuadEffect_ClassID,
130        kGrRadialGradient_ClassID,
131        kGrRectBlurEffect_ClassID,
132        kGrRRectBlurEffect_ClassID,
133        kGrRRectShadowGeoProc_ClassID,
134        kGrSimpleTextureEffect_ClassID,
135        kGrSpecularLightingEffect_ClassID,
136        kGrSRGBEffect_ClassID,
137        kGrSweepGradient_ClassID,
138        kGrTextureDomainEffect_ClassID,
139        kGrUnpremulInputFragmentProcessor_ClassID,
140        kGrYUVtoRGBEffect_ClassID,
141        kHighContrastFilterEffect_ClassID,
142        kInstanceProcessor_ClassID,
143        kLatticeGP_ClassID,
144        kLumaColorFilterEffect_ClassID,
145        kMSAAQuadProcessor_ClassID,
146        kPDLCDXferProcessor_ClassID,
147        kPorterDuffXferProcessor_ClassID,
148        kPremulFragmentProcessor_ClassID,
149        kQuadEdgeEffect_ClassID,
150        kReplaceInputFragmentProcessor_ClassID,
151        kRRectsGaussianEdgeFP_ClassID,
152        kSeriesFragmentProcessor_ClassID,
153        kShaderPDXferProcessor_ClassID,
154        kSwizzleFragmentProcessor_ClassID,
155        kTestFP_ClassID,
156        kTextureGeometryProcessor_ClassID,
157    };
158
159    virtual ~GrProcessor() = default;
160
161    /** Human-meaningful string to identify this prcoessor; may be embedded in generated shader
162        code. */
163    virtual const char* name() const = 0;
164
165    /** Human-readable dump of all information */
166    virtual SkString dumpInfo() const {
167        SkString str;
168        str.appendf("Missing data");
169        return str;
170    }
171
172    void* operator new(size_t size);
173    void operator delete(void* target);
174
175    void* operator new(size_t size, void* placement) {
176        return ::operator new(size, placement);
177    }
178    void operator delete(void* target, void* placement) {
179        ::operator delete(target, placement);
180    }
181
182    /** Helper for down-casting to a GrProcessor subclass */
183    template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
184
185    ClassID classID() const { return fClassID; }
186
187protected:
188    GrProcessor(ClassID classID) : fClassID(classID) {}
189
190private:
191    GrProcessor(const GrProcessor&) = delete;
192    GrProcessor& operator=(const GrProcessor&) = delete;
193
194    ClassID fClassID;
195};
196
197/** A GrProcessor with the ability to access textures, buffers, and image storages. */
198class GrResourceIOProcessor : public GrProcessor {
199public:
200    class TextureSampler;
201    class BufferAccess;
202
203    int numTextureSamplers() const { return fTextureSamplers.count(); }
204
205    /** Returns the access pattern for the texture at index. index must be valid according to
206        numTextureSamplers(). */
207    const TextureSampler& textureSampler(int index) const { return *fTextureSamplers[index]; }
208
209    int numBuffers() const { return fBufferAccesses.count(); }
210
211    /** Returns the access pattern for the buffer at index. index must be valid according to
212        numBuffers(). */
213    const BufferAccess& bufferAccess(int index) const { return *fBufferAccesses[index]; }
214
215    bool instantiate(GrResourceProvider* resourceProvider) const;
216
217protected:
218    GrResourceIOProcessor(ClassID classID)
219    : INHERITED(classID) {}
220
221    /**
222     * Subclasses call these from their constructor to register sampler sources. The processor
223     * subclass manages the lifetime of the objects (these functions only store pointers). The
224     * TextureSampler and/or BufferAccess instances are typically member fields of the GrProcessor
225     * subclass. These must only be called from the constructor because GrProcessors are immutable.
226     */
227    void addTextureSampler(const TextureSampler*);
228    void addBufferAccess(const BufferAccess*);
229
230    bool hasSameSamplersAndAccesses(const GrResourceIOProcessor&) const;
231
232    // These methods can be used by derived classes that also derive from GrProgramElement.
233    void addPendingIOs() const;
234    void removeRefs() const;
235    void pendingIOComplete() const;
236
237private:
238    SkSTArray<4, const TextureSampler*, true> fTextureSamplers;
239    SkSTArray<1, const BufferAccess*, true> fBufferAccesses;
240
241    typedef GrProcessor INHERITED;
242};
243
244/**
245 * Used to represent a texture that is required by a GrResourceIOProcessor. It holds a GrTexture
246 * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
247 * account for texture origin.
248 */
249class GrResourceIOProcessor::TextureSampler {
250public:
251    /**
252     * Must be initialized before adding to a GrProcessor's texture access list.
253     */
254    TextureSampler();
255    /**
256     * This copy constructor is used by GrFragmentProcessor::clone() implementations. The copy
257     * always takes a new ref on the texture proxy as the new fragment processor will not yet be
258     * in pending execution state.
259     */
260    explicit TextureSampler(const TextureSampler& that)
261            : fProxyRef(sk_ref_sp(that.fProxyRef.get()), that.fProxyRef.ioType())
262            , fSamplerState(that.fSamplerState)
263            , fVisibility(that.fVisibility) {}
264
265    TextureSampler(sk_sp<GrTextureProxy>, const GrSamplerState&);
266
267    explicit TextureSampler(sk_sp<GrTextureProxy>,
268                            GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
269                            GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
270                            GrShaderFlags visibility = kFragment_GrShaderFlag);
271
272    TextureSampler& operator=(const TextureSampler&) = delete;
273
274    void reset(sk_sp<GrTextureProxy>, const GrSamplerState&,
275               GrShaderFlags visibility = kFragment_GrShaderFlag);
276    void reset(sk_sp<GrTextureProxy>,
277               GrSamplerState::Filter = GrSamplerState::Filter::kNearest,
278               GrSamplerState::WrapMode wrapXAndY = GrSamplerState::WrapMode::kClamp,
279               GrShaderFlags visibility = kFragment_GrShaderFlag);
280
281    bool operator==(const TextureSampler& that) const {
282        return this->proxy()->underlyingUniqueID() == that.proxy()->underlyingUniqueID() &&
283               fSamplerState == that.fSamplerState && fVisibility == that.fVisibility;
284    }
285
286    bool operator!=(const TextureSampler& other) const { return !(*this == other); }
287
288    // 'instantiate' should only ever be called at flush time.
289    bool instantiate(GrResourceProvider* resourceProvider) const {
290        return SkToBool(fProxyRef.get()->instantiate(resourceProvider));
291    }
292
293    // 'peekTexture' should only ever be called after a successful 'instantiate' call
294    GrTexture* peekTexture() const {
295        SkASSERT(fProxyRef.get()->priv().peekTexture());
296        return fProxyRef.get()->priv().peekTexture();
297    }
298
299    GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); }
300    GrShaderFlags visibility() const { return fVisibility; }
301    const GrSamplerState& samplerState() const { return fSamplerState; }
302
303    bool isInitialized() const { return SkToBool(fProxyRef.get()); }
304    /**
305     * For internal use by GrProcessor.
306     */
307    const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; }
308
309private:
310    GrSurfaceProxyRef fProxyRef;
311    GrSamplerState fSamplerState;
312    GrShaderFlags fVisibility;
313};
314
315/**
316 * Used to represent a texel buffer that will be read in a GrResourceIOProcessor. It holds a
317 * GrBuffer along with an associated offset and texel config.
318 */
319class GrResourceIOProcessor::BufferAccess {
320public:
321    BufferAccess() = default;
322    BufferAccess(GrPixelConfig texelConfig, GrBuffer* buffer,
323                 GrShaderFlags visibility = kFragment_GrShaderFlag) {
324        this->reset(texelConfig, buffer, visibility);
325    }
326    /**
327     * This copy constructor is used by GrFragmentProcessor::clone() implementations. The copy
328     * always takes a new ref on the buffer proxy as the new fragment processor will not yet be
329     * in pending execution state.
330     */
331    explicit BufferAccess(const BufferAccess& that) {
332        this->reset(that.fTexelConfig, that.fBuffer.get(), that.fVisibility);
333    }
334
335    BufferAccess& operator=(const BufferAccess&) = delete;
336
337    /**
338     * Must be initialized before adding to a GrProcessor's buffer access list.
339     */
340    void reset(GrPixelConfig texelConfig, GrBuffer* buffer,
341               GrShaderFlags visibility = kFragment_GrShaderFlag) {
342        fTexelConfig = texelConfig;
343        fBuffer.set(SkRef(buffer), kRead_GrIOType);
344        fVisibility = visibility;
345    }
346
347    bool operator==(const BufferAccess& that) const {
348        return fTexelConfig == that.fTexelConfig &&
349               this->buffer() == that.buffer() &&
350               fVisibility == that.fVisibility;
351    }
352
353    bool operator!=(const BufferAccess& that) const { return !(*this == that); }
354
355    GrPixelConfig texelConfig() const { return fTexelConfig; }
356    GrBuffer* buffer() const { return fBuffer.get(); }
357    GrShaderFlags visibility() const { return fVisibility; }
358
359    /**
360     * For internal use by GrProcessor.
361     */
362    const GrGpuResourceRef* programBuffer() const { return &fBuffer;}
363
364private:
365    GrPixelConfig fTexelConfig;
366    GrTGpuResourceRef<GrBuffer> fBuffer;
367    GrShaderFlags fVisibility;
368
369    typedef SkNoncopyable INHERITED;
370};
371
372#endif
373