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