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 |