Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrXferProcessor_DEFINED | 8 #ifndef GrXferProcessor_DEFINED |
| 9 #define GrXferProcessor_DEFINED | 9 #define GrXferProcessor_DEFINED |
| 10 | 10 |
| 11 #include "GrColor.h" | 11 #include "GrColor.h" |
| 12 #include "GrProcessor.h" | 12 #include "GrProcessor.h" |
| 13 #include "GrTexture.h" | 13 #include "GrTexture.h" |
| 14 #include "GrTypes.h" | 14 #include "GrTypes.h" |
| 15 #include "SkXfermode.h" | 15 #include "SkXfermode.h" |
| 16 | 16 |
| 17 class GrPipelineBuilder; | |
| 17 class GrShaderCaps; | 18 class GrShaderCaps; |
| 18 class GrGLSLCaps; | 19 class GrGLSLCaps; |
| 19 class GrGLXferProcessor; | 20 class GrGLXferProcessor; |
| 20 class GrProcOptInfo; | 21 class GrProcOptInfo; |
| 21 | 22 |
| 22 /** | 23 /** |
| 23 * Equations for alpha-blending. | 24 * Equations for alpha-blending. |
| 24 */ | 25 */ |
| 25 enum GrBlendEquation { | 26 enum GrBlendEquation { |
| 26 // Basic blend equations. | 27 // Basic blend equations. |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 221 | 222 |
| 222 SkDEBUGCODE(SkString dump() const;) | 223 SkDEBUGCODE(SkString dump() const;) |
| 223 | 224 |
| 224 GrBlendEquation fEquation; | 225 GrBlendEquation fEquation; |
| 225 GrBlendCoeff fSrcBlend; | 226 GrBlendCoeff fSrcBlend; |
| 226 GrBlendCoeff fDstBlend; | 227 GrBlendCoeff fDstBlend; |
| 227 GrColor fBlendConstant; | 228 GrColor fBlendConstant; |
| 228 bool fWriteColor; | 229 bool fWriteColor; |
| 229 }; | 230 }; |
| 230 | 231 |
| 231 void getBlendInfo(BlendInfo* blendInfo) const { | 232 void getBlendInfo(BlendInfo* blendInfo) const; |
| 232 blendInfo->reset(); | |
| 233 this->onGetBlendInfo(blendInfo); | |
| 234 } | |
| 235 | 233 |
| 236 bool willReadDstColor() const { return fWillReadDstColor; } | 234 bool willReadDstColor() const { return fWillReadDstColor; } |
| 237 | 235 |
| 238 /** | 236 /** |
| 239 * Returns the texture to be used as the destination when reading the dst in the fragment | 237 * Returns the texture to be used as the destination when reading the dst in the fragment |
| 240 * shader. If the returned texture is NULL then the XP is either not reading the dst or we have | 238 * shader. If the returned texture is NULL then the XP is either not reading the dst or we have |
| 241 * extentions that support framebuffer fetching and thus don't need a copy o f the dst texture. | 239 * extentions that support framebuffer fetching and thus don't need a copy o f the dst texture. |
| 242 */ | 240 */ |
| 243 const GrTexture* getDstTexture() const { return fDstTexture.getTexture(); } | 241 const GrTexture* getDstTexture() const { return fDstTexture.getTexture(); } |
| 244 | 242 |
| 245 /** | 243 /** |
| 246 * Returns the offset in device coords to use when accessing the dst texture to get the dst | 244 * Returns the offset in device coords to use when accessing the dst texture to get the dst |
| 247 * pixel color in the shader. This value is only valid if getDstTexture() != NULL. | 245 * pixel color in the shader. This value is only valid if getDstTexture() != NULL. |
| 248 */ | 246 */ |
| 249 const SkIPoint& dstTextureOffset() const { | 247 const SkIPoint& dstTextureOffset() const { |
| 250 SkASSERT(this->getDstTexture()); | 248 SkASSERT(this->getDstTexture()); |
| 251 return fDstTextureOffset; | 249 return fDstTextureOffset; |
| 252 } | 250 } |
| 253 | 251 |
| 254 /** | 252 /** |
| 253 * If we are performing a dst read, returns whether this class will use mixe d samples to | |
| 254 * antialias the shader's final output. (If not doing a dst read, the subcla ss is responsible to | |
| 255 * account for any mixed samples.) | |
| 256 */ | |
| 257 bool dstReadUsesMixedSamples() const { return fDstReadUsesMixedSamples; } | |
| 258 | |
| 259 /** | |
| 255 * Returns whether or not the XP will look at coverage when doing its blendi ng. | 260 * Returns whether or not the XP will look at coverage when doing its blendi ng. |
| 256 */ | 261 */ |
| 257 bool readsCoverage() const { return fReadsCoverage; } | 262 bool readsCoverage() const { return fReadsCoverage; } |
| 258 | 263 |
| 259 /** | 264 /** |
| 260 * Returns whether or not this xferProcossor will set a secondary output to be used with dual | 265 * Returns whether or not this xferProcossor will set a secondary output to be used with dual |
| 261 * source blending. | 266 * source blending. |
| 262 */ | 267 */ |
| 263 virtual bool hasSecondaryOutput() const { return false; } | 268 bool hasSecondaryOutput() const; |
| 264 | 269 |
| 265 /** Returns true if this and other processor conservatively draw identically . It can only return | 270 /** Returns true if this and other processor conservatively draw identically . It can only return |
| 266 true when the two processor are of the same subclass (i.e. they return t he same object from | 271 true when the two processor are of the same subclass (i.e. they return t he same object from |
| 267 from getFactory()). | 272 from getFactory()). |
| 268 | 273 |
| 269 A return value of true from isEqual() should not be used to test whether the processor would | 274 A return value of true from isEqual() should not be used to test whether the processor would |
| 270 generate the same shader code. To test for identical code generation use getGLProcessorKey*/ | 275 generate the same shader code. To test for identical code generation use getGLProcessorKey*/ |
| 271 | 276 |
| 272 bool isEqual(const GrXferProcessor& that) const { | 277 bool isEqual(const GrXferProcessor& that) const { |
| 273 if (this->classID() != that.classID()) { | 278 if (this->classID() != that.classID()) { |
| 274 return false; | 279 return false; |
| 275 } | 280 } |
| 276 if (this->fWillReadDstColor != that.fWillReadDstColor) { | 281 if (this->fWillReadDstColor != that.fWillReadDstColor) { |
| 277 return false; | 282 return false; |
| 278 } | 283 } |
| 279 if (this->fReadsCoverage != that.fReadsCoverage) { | 284 if (this->fReadsCoverage != that.fReadsCoverage) { |
| 280 return false; | 285 return false; |
| 281 } | 286 } |
| 282 if (this->fDstTexture.getTexture() != that.fDstTexture.getTexture()) { | 287 if (this->fDstTexture.getTexture() != that.fDstTexture.getTexture()) { |
| 283 return false; | 288 return false; |
| 284 } | 289 } |
| 285 if (this->fDstTextureOffset != that.fDstTextureOffset) { | 290 if (this->fDstTextureOffset != that.fDstTextureOffset) { |
| 286 return false; | 291 return false; |
| 287 } | 292 } |
| 293 if (this->fDstReadUsesMixedSamples != that.fDstReadUsesMixedSamples) { | |
| 294 return false; | |
| 295 } | |
| 288 return this->onIsEqual(that); | 296 return this->onIsEqual(that); |
| 289 } | 297 } |
| 290 | 298 |
| 291 protected: | 299 protected: |
| 292 GrXferProcessor(); | 300 GrXferProcessor(); |
| 293 GrXferProcessor(const DstTexture*, bool willReadDstColor); | 301 GrXferProcessor(const GrPipelineBuilder&, const DstTexture*, bool willReadDs tColor); |
| 294 | 302 |
| 295 private: | 303 private: |
| 296 virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 304 virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 297 const GrProcOptInfo& coveragePOI, | 305 const GrProcOptInfo& coveragePOI, |
| 298 bool doesStencilWrite, | 306 bool doesStencilWrite, |
| 299 GrColor* overrideColor, | 307 GrColor* overrideColor, |
| 300 const GrCaps& caps) = 0; | 308 const GrCaps& caps) = 0; |
| 301 | 309 |
| 302 /** | 310 /** |
| 303 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this xfer | 311 * Sets a unique key on the GrProcessorKeyBuilder that is directly associate d with this xfer |
| 304 * processor's GL backend implementation. | 312 * processor's GL backend implementation. |
| 305 */ | 313 */ |
| 306 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, | 314 virtual void onGetGLProcessorKey(const GrGLSLCaps& caps, |
| 307 GrProcessorKeyBuilder* b) const = 0; | 315 GrProcessorKeyBuilder* b) const = 0; |
| 308 | 316 |
| 309 /** | 317 /** |
| 310 * If not using a texture barrier, retrieves whether the subclass will requi re a different type | 318 * If not using a texture barrier, retrieves whether the subclass will requi re a different type |
| 311 * of barrier. | 319 * of barrier. |
| 312 */ | 320 */ |
| 313 virtual bool onWillNeedXferBarrier(const GrRenderTarget*, | 321 virtual bool onWillNeedXferBarrier(const GrRenderTarget*, |
| 314 const GrCaps&, | 322 const GrCaps&, |
| 315 GrXferBarrierType* outBarrierType SK_UNUS ED) const { | 323 GrXferBarrierType* outBarrierType SK_UNUS ED) const { |
| 316 return false; | 324 return false; |
| 317 } | 325 } |
| 318 | 326 |
| 319 /** | 327 /** |
| 320 * Retrieves the hardware blend state required by this Xfer processor. The B lendInfo struct | 328 * If we are not performing a dst read, returns whether the subclass will se t a secondary |
| 321 * comes initialized to default values, so the Xfer processor only needs to set the state it | 329 * output. If we are doing a dst read, the base class controls the secondary output and this |
| 322 * needs. It may not even need to override this method at all. | 330 * method will not be called. |
| 331 */ | |
| 332 virtual bool onHasSecondaryOutput() const { return false; } | |
| 333 | |
| 334 /** | |
| 335 * If we are not performing a dst read, retrieves the fixed-function blend s tate required by the | |
| 336 * subclass. If we are doing a dst read, the base class controls the fixed-f unction blend state | |
| 337 * and this method will not be called. The BlendInfo struct comes initialize d to "no blending". | |
| 323 */ | 338 */ |
| 324 virtual void onGetBlendInfo(BlendInfo*) const {} | 339 virtual void onGetBlendInfo(BlendInfo*) const {} |
| 325 | 340 |
| 326 virtual bool onIsEqual(const GrXferProcessor&) const = 0; | 341 virtual bool onIsEqual(const GrXferProcessor&) const = 0; |
| 327 | 342 |
| 328 bool fWillReadDstColor; | 343 bool fWillReadDstColor; |
| 344 bool fDstReadUsesMixedSamples; | |
| 329 bool fReadsCoverage; | 345 bool fReadsCoverage; |
| 330 SkIPoint fDstTextureOffset; | 346 SkIPoint fDstTextureOffset; |
| 331 GrTextureAccess fDstTexture; | 347 GrTextureAccess fDstTexture; |
| 332 | 348 |
| 333 typedef GrFragmentProcessor INHERITED; | 349 typedef GrFragmentProcessor INHERITED; |
| 334 }; | 350 }; |
| 335 | 351 |
| 336 GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); | 352 GR_MAKE_BITFIELD_OPS(GrXferProcessor::OptFlags); |
| 337 | 353 |
| 338 /////////////////////////////////////////////////////////////////////////////// | 354 /////////////////////////////////////////////////////////////////////////////// |
| 339 | 355 |
| 340 /** | 356 /** |
| 341 * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is | 357 * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is |
| 342 * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the | 358 * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the |
| 343 * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF a long with all the | 359 * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF a long with all the |
| 344 * draw information to create a GrXferProcessor (XP) which can implement the des ired blending for | 360 * draw information to create a GrXferProcessor (XP) which can implement the des ired blending for |
| 345 * the draw. | 361 * the draw. |
| 346 * | 362 * |
| 347 * Before the XP is created, the XPF is able to answer queries about what functi onality the XPs it | 363 * Before the XP is created, the XPF is able to answer queries about what functi onality the XPs it |
| 348 * creates will have. For example, can it create an XP that supports RGB coverag e or will the XP | 364 * creates will have. For example, can it create an XP that supports RGB coverag e or will the XP |
| 349 * blend with the destination color. | 365 * blend with the destination color. |
| 350 */ | 366 */ |
| 351 class GrXPFactory : public SkRefCnt { | 367 class GrXPFactory : public SkRefCnt { |
| 352 public: | 368 public: |
| 353 typedef GrXferProcessor::DstTexture DstTexture; | 369 typedef GrXferProcessor::DstTexture DstTexture; |
| 354 GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI, | 370 GrXferProcessor* createXferProcessor(const GrPipelineBuilder&, |
|
Chris Dalton
2015/06/04 01:19:18
I thought it might be nicer to just send in a Pipe
| |
| 371 const GrProcOptInfo& colorPOI, | |
| 355 const GrProcOptInfo& coveragePOI, | 372 const GrProcOptInfo& coveragePOI, |
| 356 const DstTexture*, | 373 const DstTexture*, |
| 357 const GrCaps& caps) const; | 374 const GrCaps& caps) const; |
| 358 | 375 |
| 359 /** | 376 /** |
| 360 * This function returns true if the GrXferProcessor generated from this fac tory will be able to | 377 * This function returns true if the GrXferProcessor generated from this fac tory will be able to |
| 361 * correctly blend when using RGB coverage. The knownColor and knownColorFla gs represent the | 378 * correctly blend when using RGB coverage. The knownColor and knownColorFla gs represent the |
| 362 * final computed color from the color stages. | 379 * final computed color from the color stages. |
| 363 */ | 380 */ |
| 364 virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlag s) const = 0; | 381 virtual bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlag s) const = 0; |
| 365 | 382 |
| 366 /** | 383 /** |
| 367 * Known color information after blending, but before accounting for any cov erage. | 384 * Known color information after blending, but before accounting for any cov erage. |
| 368 */ | 385 */ |
| 369 struct InvariantBlendedColor { | 386 struct InvariantBlendedColor { |
| 370 bool fWillBlendWithDst; | 387 bool fWillBlendWithDst; |
| 371 GrColor fKnownColor; | 388 GrColor fKnownColor; |
| 372 GrColorComponentFlags fKnownColorFlags; | 389 GrColorComponentFlags fKnownColorFlags; |
| 373 }; | 390 }; |
| 374 | 391 |
| 375 /** | 392 /** |
| 376 * Returns information about the output color, produced by XPs from this fac tory, that will be | 393 * Returns information about the output color, produced by XPs from this fac tory, that will be |
| 377 * known after blending. Note that we can conflate coverage and color, so th e actual values | 394 * known after blending. Note that we can conflate coverage and color, so th e actual values |
| 378 * written to pixels with partial coverage may not always seem consistent wi th the invariant | 395 * written to pixels with partial coverage may not always seem consistent wi th the invariant |
| 379 * information returned by this function. | 396 * information returned by this function. |
| 380 */ | 397 */ |
| 381 virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, | 398 virtual void getInvariantBlendedColor(const GrProcOptInfo& colorPOI, |
| 382 InvariantBlendedColor*) const = 0; | 399 InvariantBlendedColor*) const = 0; |
| 383 | 400 |
| 384 bool willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI, | 401 bool willNeedDstTexture(const GrCaps& caps, const GrPipelineBuilder&, |
| 385 const GrProcOptInfo& coveragePOI) const; | 402 const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const; |
| 386 | 403 |
| 387 bool isEqual(const GrXPFactory& that) const { | 404 bool isEqual(const GrXPFactory& that) const { |
| 388 if (this->classID() != that.classID()) { | 405 if (this->classID() != that.classID()) { |
| 389 return false; | 406 return false; |
| 390 } | 407 } |
| 391 return this->onIsEqual(that); | 408 return this->onIsEqual(that); |
| 392 } | 409 } |
| 393 | 410 |
| 394 /** | 411 /** |
| 395 * Helper for down-casting to a GrXPFactory subclass | 412 * Helper for down-casting to a GrXPFactory subclass |
| 396 */ | 413 */ |
| 397 template <typename T> const T& cast() const { return *static_cast<const T*>( this); } | 414 template <typename T> const T& cast() const { return *static_cast<const T*>( this); } |
| 398 | 415 |
| 399 uint32_t classID() const { SkASSERT(kIllegalXPFClassID != fClassID); return fClassID; } | 416 uint32_t classID() const { SkASSERT(kIllegalXPFClassID != fClassID); return fClassID; } |
| 400 | 417 |
| 401 protected: | 418 protected: |
| 402 GrXPFactory() : fClassID(kIllegalXPFClassID) {} | 419 GrXPFactory() : fClassID(kIllegalXPFClassID) {} |
| 403 | 420 |
| 404 template <typename XPF_SUBCLASS> void initClassID() { | 421 template <typename XPF_SUBCLASS> void initClassID() { |
| 405 static uint32_t kClassID = GenClassID(); | 422 static uint32_t kClassID = GenClassID(); |
| 406 fClassID = kClassID; | 423 fClassID = kClassID; |
| 407 } | 424 } |
| 408 | 425 |
| 409 uint32_t fClassID; | 426 uint32_t fClassID; |
| 410 | 427 |
| 411 private: | 428 private: |
| 412 virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, | 429 virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps, |
| 430 const GrPipelineBuilder&, | |
| 413 const GrProcOptInfo& colorPOI , | 431 const GrProcOptInfo& colorPOI , |
| 414 const GrProcOptInfo& coverage POI, | 432 const GrProcOptInfo& coverage POI, |
| 415 const DstTexture*) const = 0; | 433 const DstTexture*) const = 0; |
| 416 /** | 434 /** |
| 417 * Returns true if the XP generated by this factory will explicitly read ds t in the fragment | 435 * Returns true if the XP generated by this factory will explicitly read ds t in the fragment |
| 418 * shader. | 436 * shader. |
| 419 */ | 437 */ |
| 420 virtual bool willReadDstColor(const GrCaps& caps, | 438 virtual bool willReadDstColor(const GrCaps& caps, |
| 439 const GrPipelineBuilder&, | |
| 421 const GrProcOptInfo& colorPOI, | 440 const GrProcOptInfo& colorPOI, |
| 422 const GrProcOptInfo& coveragePOI) const = 0; | 441 const GrProcOptInfo& coveragePOI) const = 0; |
| 423 | 442 |
| 424 virtual bool onIsEqual(const GrXPFactory&) const = 0; | 443 virtual bool onIsEqual(const GrXPFactory&) const = 0; |
| 425 | 444 |
| 426 static uint32_t GenClassID() { | 445 static uint32_t GenClassID() { |
| 427 // fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The | 446 // fCurrXPFactoryID has been initialized to kIllegalXPFactoryID. The |
| 428 // atomic inc returns the old value not the incremented value. So we add | 447 // atomic inc returns the old value not the incremented value. So we add |
| 429 // 1 to the returned value. | 448 // 1 to the returned value. |
| 430 uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrXPFClassID)) + 1 ; | 449 uint32_t id = static_cast<uint32_t>(sk_atomic_inc(&gCurrXPFClassID)) + 1 ; |
| 431 if (!id) { | 450 if (!id) { |
| 432 SkFAIL("This should never wrap as it should only be called once for each GrXPFactory " | 451 SkFAIL("This should never wrap as it should only be called once for each GrXPFactory " |
| 433 "subclass."); | 452 "subclass."); |
| 434 } | 453 } |
| 435 return id; | 454 return id; |
| 436 } | 455 } |
| 437 | 456 |
| 438 enum { | 457 enum { |
| 439 kIllegalXPFClassID = 0, | 458 kIllegalXPFClassID = 0, |
| 440 }; | 459 }; |
| 441 static int32_t gCurrXPFClassID; | 460 static int32_t gCurrXPFClassID; |
| 442 | 461 |
| 443 typedef GrProgramElement INHERITED; | 462 typedef GrProgramElement INHERITED; |
| 444 }; | 463 }; |
| 445 | 464 |
| 446 #endif | 465 #endif |
| 447 | 466 |
| OLD | NEW |