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: GrProcessorKeyBuilder(SkTArray<unsigned char,true> * data)36 GrProcessorKeyBuilder(SkTArray<unsigned char, true>* data) : fData(data), fCount(0) { 37 SkASSERT(0 == fData->count() % sizeof(uint32_t)); 38 } 39 add32(uint32_t v)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. */ add32n(int count)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 size()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 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 */ dumpInfo()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 new(size_t size,void * placement)175 void* operator new(size_t size, void* placement) { 176 return ::operator new(size, placement); 177 } delete(void * target,void * placement)178 void operator delete(void* target, void* placement) { 179 ::operator delete(target, placement); 180 } 181 182 /** Helper for down-casting to a GrProcessor subclass */ cast()183 template <typename T> const T& cast() const { return *static_cast<const T*>(this); } 184 classID()185 ClassID classID() const { return fClassID; } 186 187 protected: GrProcessor(ClassID classID)188 GrProcessor(ClassID classID) : fClassID(classID) {} 189 190 private: 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. */ 198 class GrResourceIOProcessor : public GrProcessor { 199 public: 200 class TextureSampler; 201 class BufferAccess; 202 numTextureSamplers()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(). */ textureSampler(int index)207 const TextureSampler& textureSampler(int index) const { return *fTextureSamplers[index]; } 208 numBuffers()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(). */ bufferAccess(int index)213 const BufferAccess& bufferAccess(int index) const { return *fBufferAccesses[index]; } 214 215 bool instantiate(GrResourceProvider* resourceProvider) const; 216 217 protected: GrResourceIOProcessor(ClassID classID)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 237 private: 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 */ 249 class GrResourceIOProcessor::TextureSampler { 250 public: 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 */ TextureSampler(const TextureSampler & that)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. instantiate(GrResourceProvider * resourceProvider)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 peekTexture()294 GrTexture* peekTexture() const { 295 SkASSERT(fProxyRef.get()->priv().peekTexture()); 296 return fProxyRef.get()->priv().peekTexture(); 297 } 298 proxy()299 GrTextureProxy* proxy() const { return fProxyRef.get()->asTextureProxy(); } visibility()300 GrShaderFlags visibility() const { return fVisibility; } samplerState()301 const GrSamplerState& samplerState() const { return fSamplerState; } 302 isInitialized()303 bool isInitialized() const { return SkToBool(fProxyRef.get()); } 304 /** 305 * For internal use by GrProcessor. 306 */ programProxy()307 const GrSurfaceProxyRef* programProxy() const { return &fProxyRef; } 308 309 private: 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 */ 319 class GrResourceIOProcessor::BufferAccess { 320 public: 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 */ BufferAccess(const BufferAccess & that)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 texelConfig()355 GrPixelConfig texelConfig() const { return fTexelConfig; } buffer()356 GrBuffer* buffer() const { return fBuffer.get(); } visibility()357 GrShaderFlags visibility() const { return fVisibility; } 358 359 /** 360 * For internal use by GrProcessor. 361 */ programBuffer()362 const GrGpuResourceRef* programBuffer() const { return &fBuffer;} 363 364 private: 365 GrPixelConfig fTexelConfig; 366 GrTGpuResourceRef<GrBuffer> fBuffer; 367 GrShaderFlags fVisibility; 368 369 typedef SkNoncopyable INHERITED; 370 }; 371 372 #endif 373