Add helper for creating leaf FPs inside GrFP::TestCreate functions
authorbsalomon <bsalomon@google.com>
Mon, 14 Sep 2015 20:16:26 +0000 (13:16 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 14 Sep 2015 20:16:26 +0000 (13:16 -0700)
Review URL: https://codereview.chromium.org/1334273003

gyp/gpu.gypi
include/gpu/GrProcessorUnitTest.h
include/gpu/effects/GrExtractAlphaFragmentProcessor.h
src/gpu/GrProcessor.cpp
src/gpu/GrProcessorUnitTest.cpp [new file with mode: 0644]
src/gpu/effects/GrExtractAlphaFragmentProcessor.cpp
src/gpu/effects/GrXfermodeFragmentProcessor.cpp

index f8dad9e..2f095d1 100644 (file)
       '<(skia_src_path)/gpu/GrProgramDesc.h',
       '<(skia_src_path)/gpu/GrProgramElement.cpp',
       '<(skia_src_path)/gpu/GrProcessor.cpp',
+      '<(skia_src_path)/gpu/GrProcessorUnitTest.cpp',
       '<(skia_src_path)/gpu/GrProcessorDataManager.cpp',
       '<(skia_src_path)/gpu/GrProcOptInfo.cpp',
       '<(skia_src_path)/gpu/GrProcOptInfo.h',
index 8a17521..b18c707 100644 (file)
 class SkMatrix;
 class GrCaps;
 class GrContext;
+struct GrProcessorTestData;
 
 namespace GrProcessorUnitTest {
+
 // Used to access the dummy textures in TestCreate procs.
 enum {
     kSkiaPMTextureIdx = 0,
     kAlphaTextureIdx = 1,
 };
 
+/** This allows parent FPs to implement a test create with known leaf children in order to avoid
+creating an unbounded FP tree which may overflow various shader limits. */
+const GrFragmentProcessor* CreateChildFP(GrProcessorTestData*);
+
 }
 
 /*
@@ -57,10 +63,8 @@ struct GrProcessorTestData {
 class GrProcessor;
 class GrTexture;
 
-template <class Processor>
-class GrProcessorTestFactory : SkNoncopyable {
+template <class Processor> class GrProcessorTestFactory : SkNoncopyable {
 public:
-
     typedef const Processor* (*CreateProc)(GrProcessorTestData*);
 
     GrProcessorTestFactory(CreateProc createProc) {
@@ -111,7 +115,6 @@ private:
     static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED;                             \
     static const GrXPFactory* TestCreate(GrProcessorTestData*)
 
-
 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
  *  also implement this static function:
  *      GrProcessor* TestCreate(GrProcessorTestData*);
index d26f00f..59ae019 100644 (file)
@@ -39,6 +39,8 @@ private:
 
     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
 
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
+
     typedef GrFragmentProcessor INHERITED;
 };
 
index 6ab5561..782b82b 100644 (file)
@@ -50,7 +50,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
  * we verify the count is as expected.  If a new factory is added, then these numbers must be
  * manually adjusted.
  */
-static const int kFPFactoryCount = 38;
+static const int kFPFactoryCount = 39;
 static const int kGPFactoryCount = 14;
 static const int kXPFactoryCount = 5;
 
diff --git a/src/gpu/GrProcessorUnitTest.cpp b/src/gpu/GrProcessorUnitTest.cpp
new file mode 100644 (file)
index 0000000..bdc602c
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrProcessorUnitTest.h"
+#include "GrFragmentProcessor.h"
+
+const GrFragmentProcessor* GrProcessorUnitTest::CreateChildFP(GrProcessorTestData* data) {
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+    SkAutoTUnref<const GrFragmentProcessor> fp;
+    do {
+        fp.reset(GrProcessorTestFactory<GrFragmentProcessor>::Create(data));
+        SkASSERT(fp);
+    } while (fp->numChildProcessors() != 0);
+    return SkRef(fp.get());
+#else
+    SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS");
+    return nullptr;
+#endif
+}
index 8f6af65..483df64 100644 (file)
@@ -47,3 +47,10 @@ void GrExtractAlphaFragmentProcessor::onComputeInvariantOutput(GrInvariantOutput
     }
     this->childProcessor(0).computeInvariantOutput(inout);
 }
+
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrExtractAlphaFragmentProcessor);
+
+const GrFragmentProcessor* GrExtractAlphaFragmentProcessor::TestCreate(GrProcessorTestData* d) {
+    SkAutoTUnref<const GrFragmentProcessor> child(GrProcessorUnitTest::CreateChildFP(d));
+    return SkNEW_ARGS(GrExtractAlphaFragmentProcessor, (child));
+}
index c039db3..ab944d8 100644 (file)
@@ -72,28 +72,13 @@ private:
 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrComposeTwoFragmentProcessor);
 
 const GrFragmentProcessor* GrComposeTwoFragmentProcessor::TestCreate(GrProcessorTestData* d) {
-#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     // Create two random frag procs.
-    // For now, we'll prevent either children from being a shader with children to prevent the
-    // possibility of an arbitrarily large tree of procs.
-    SkAutoTUnref<const GrFragmentProcessor> fpA;
-    do {
-        fpA.reset(GrProcessorTestFactory<GrFragmentProcessor>::Create(d));
-        SkASSERT(fpA);
-    } while (fpA->numChildProcessors() != 0);
-    SkAutoTUnref<const GrFragmentProcessor> fpB;
-    do {
-        fpB.reset(GrProcessorTestFactory<GrFragmentProcessor>::Create(d));
-        SkASSERT(fpB);
-    } while (fpB->numChildProcessors() != 0);
+    SkAutoTUnref<const GrFragmentProcessor> fpA(GrProcessorUnitTest::CreateChildFP(d));
+    SkAutoTUnref<const GrFragmentProcessor> fpB(GrProcessorUnitTest::CreateChildFP(d));
 
     SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(
             d->fRandom->nextRangeU(0, SkXfermode::kLastCoeffMode));
     return SkNEW_ARGS(GrComposeTwoFragmentProcessor, (fpA, fpB, mode));
-#else
-    SkFAIL("Should not be called if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS");
-    return nullptr;
-#endif
 }
 
 GrGLFragmentProcessor* GrComposeTwoFragmentProcessor::onCreateGLInstance() const{