Force linking of static member variables for GLPrograms
authorjoshualitt <joshualitt@chromium.org>
Thu, 9 Oct 2014 20:12:35 +0000 (13:12 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 9 Oct 2014 20:12:35 +0000 (13:12 -0700)
BUG=skia:

Review URL: https://codereview.chromium.org/614163002

include/gpu/GrProcessorUnitTest.h
src/gpu/GrProcessor.cpp
tests/GLProgramsTest.cpp

index 04ab2d1..3e1601d 100644 (file)
@@ -40,9 +40,9 @@ class GrProcessorTestFactory : SkNoncopyable {
 public:
 
     typedef Processor* (*CreateProc)(SkRandom*,
-                                    GrContext*,
-                                    const GrDrawTargetCaps& caps,
-                                    GrTexture* dummyTextures[]);
+                                     GrContext*,
+                                     const GrDrawTargetCaps& caps,
+                                     GrTexture* dummyTextures[]);
 
     GrProcessorTestFactory(CreateProc createProc) {
         fCreateProc = createProc;
@@ -50,42 +50,43 @@ public:
     }
 
     static Processor* CreateStage(SkRandom* random,
-                                 GrContext* context,
-                                 const GrDrawTargetCaps& caps,
-                                 GrTexture* dummyTextures[]) {
+                                  GrContext* context,
+                                  const GrDrawTargetCaps& caps,
+                                  GrTexture* dummyTextures[]) {
+        VerifyFactoryCount();
+        SkASSERT(GetFactories()->count());
         uint32_t idx = random->nextRangeU(0, GetFactories()->count() - 1);
         GrProcessorTestFactory<Processor>* factory = (*GetFactories())[idx];
         return factory->fCreateProc(random, context, caps, dummyTextures);
     }
 
+    /*
+     * A test function which verifies the count of factories.
+     */
+    static void VerifyFactoryCount();
+
 private:
     CreateProc fCreateProc;
 
-    #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-    static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories() {
-        static SkTArray<GrProcessorTestFactory<Processor>*, true> gFactories;
-        return &gFactories;
-    }
-    #endif
+    static SkTArray<GrProcessorTestFactory<Processor>*, true>* GetFactories();
 };
 
 /** GrProcessor subclasses should insert this macro in their declaration to be included in the
  *  program generation unit test.
  */
-
 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
-    static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory;                               \
+    static GrProcessorTestFactory<GrGeometryProcessor> gTestFactory SK_UNUSED;                     \
     static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
-                                GrContext*,                                                        \
-                                const GrDrawTargetCaps&,                                           \
-                                GrTexture* dummyTextures[2])
+                                           GrContext*,                                             \
+                                           const GrDrawTargetCaps&,                                \
+                                           GrTexture* dummyTextures[2])
 
 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
-    static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory;                               \
+    static GrProcessorTestFactory<GrFragmentProcessor> gTestFactory SK_UNUSED;                     \
     static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
-                                GrContext*,                                                        \
-                                const GrDrawTargetCaps&,                                           \
-                                GrTexture* dummyTextures[2])
+                                           GrContext*,                                             \
+                                           const GrDrawTargetCaps&,                                \
+                                           GrTexture* dummyTextures[2])
 
 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
  *  also implement this static function:
index 26e0053..71dfaae 100644 (file)
 #include "GrMemoryPool.h"
 #include "SkTLS.h"
 
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+
+/*
+ * Originally these were both in the processor unit test header, but then it seemed to cause linker
+ * problems on android.
+ */
+template<>
+SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>*
+GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
+    static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
+    return &gFactories;
+}
+
+template<>
+SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
+GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
+    static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories;
+    return &gFactories;
+}
+
+/*
+ * To ensure we always have successful static initialization, before creating from the factories
+ * we verify the count is as expected.  If a new factory is added, then these numbers must be
+ * manually adjusted.
+ */
+static const int kFPFactoryCount = 37;
+static const int kGPFactoryCount = 15;
+
+template<>
+void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
+    if (kFPFactoryCount != GetFactories()->count()) {
+        SkFAIL("Wrong number of fragment processor factories!");
+    }
+}
+
+template<>
+void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
+    if (kGPFactoryCount != GetFactories()->count()) {
+        SkFAIL("Wrong number of geometry processor factories!");
+    }
+}
+
+#endif
+
 namespace GrProcessorUnitTest {
 const SkMatrix& TestMatrix(SkRandom* random) {
     static SkMatrix gMatrices[5];
index 4d1c597..331ea78 100644 (file)
@@ -506,7 +506,22 @@ DEF_GPUTEST(GLPrograms, reporter, factory) {
         GrContext* context = factory->get(static_cast<GrContextFactory::GLContextType>(type));
         if (context) {
             GrGpuGL* gpu = static_cast<GrGpuGL*>(context->getGpu());
-            int maxStages = 6;
+
+            /*
+             * For the time being, we only support the test with desktop GL or for android on
+             * ARM platforms
+             * TODO When we run ES 3.00 GLSL in more places, test again
+             */
+            int maxStages;
+            if (kGL_GrGLStandard == gpu->glStandard() ||
+                kARM_GrGLVendor == gpu->ctxInfo().vendor()) {
+                maxStages = 6;
+            } else if (kTegra3_GrGLRenderer == gpu->ctxInfo().renderer() ||
+                       kOther_GrGLRenderer == gpu->ctxInfo().renderer()) {
+                maxStages = 1;
+            } else {
+                return;
+            }
 #if SK_ANGLE
             // Some long shaders run out of temporary registers in the D3D compiler on ANGLE.
             if (type == GrContextFactory::kANGLE_GLContextType) {
@@ -518,29 +533,4 @@ DEF_GPUTEST(GLPrograms, reporter, factory) {
     }
 }
 
-// This is evil evil evil. The linker may throw away whole translation units as dead code if it
-// thinks none of the functions are called. It will do this even if there are static initializers
-// in the unit that could pass pointers to functions from the unit out to other translation units!
-// We force some of the effects that would otherwise be discarded to link here.
-
-#include "SkAlphaThresholdFilter.h"
-#include "SkColorMatrixFilter.h"
-#include "SkLightingImageFilter.h"
-#include "SkMagnifierImageFilter.h"
-
-void forceLinking();
-
-void forceLinking() {
-    SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0);
-    SkAlphaThresholdFilter::Create(SkRegion(), .5f, .5f);
-    SkAutoTUnref<SkImageFilter> mag(SkMagnifierImageFilter::Create(
-        SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1));
-    GrConfigConversionEffect::Create(NULL,
-                                     false,
-                                     GrConfigConversionEffect::kNone_PMConversion,
-                                     SkMatrix::I());
-    SkScalar matrix[20];
-    SkAutoTUnref<SkColorMatrixFilter> cmf(SkColorMatrixFilter::Create(matrix));
-}
-
 #endif