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 #include "GrProcessor.h" 9 #include "GrContext.h" 10 #include "GrContextPriv.h" 11 #include "GrGeometryProcessor.h" 12 #include "GrMemoryPool.h" 13 #include "GrSamplerState.h" 14 #include "GrTextureProxy.h" 15 #include "GrXferProcessor.h" 16 #include "SkSpinlock.h" 17 18 #if GR_TEST_UTILS 19 20 GrResourceProvider* GrProcessorTestData::resourceProvider() { 21 return fContext->contextPriv().resourceProvider(); 22 } 23 24 GrProxyProvider* GrProcessorTestData::proxyProvider() { 25 return fContext->contextPriv().proxyProvider(); 26 } 27 28 const GrCaps* GrProcessorTestData::caps() { return fContext->contextPriv().caps(); } 29 30 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 31 class GrFragmentProcessor; 32 class GrGeometryProcessor; 33 34 /* 35 * Originally these were both in the processor unit test header, but then it seemed to cause linker 36 * problems on android. 37 */ 38 template <> 39 SkTArray<GrFragmentProcessorTestFactory*, true>* GrFragmentProcessorTestFactory::GetFactories() { 40 static SkTArray<GrFragmentProcessorTestFactory*, true> gFactories; 41 return &gFactories; 42 } 43 44 template <> 45 SkTArray<GrGeometryProcessorTestFactory*, true>* GrGeometryProcessorTestFactory::GetFactories() { 46 static SkTArray<GrGeometryProcessorTestFactory*, true> gFactories; 47 return &gFactories; 48 } 49 50 SkTArray<GrXPFactoryTestFactory*, true>* GrXPFactoryTestFactory::GetFactories() { 51 static SkTArray<GrXPFactoryTestFactory*, true> gFactories; 52 return &gFactories; 53 } 54 55 /* 56 * To ensure we always have successful static initialization, before creating from the factories 57 * we verify the count is as expected. If a new factory is added, then these numbers must be 58 * manually adjusted. 59 */ 60 static const int kFPFactoryCount = 36; 61 static const int kGPFactoryCount = 14; 62 static const int kXPFactoryCount = 4; 63 64 template <> 65 void GrFragmentProcessorTestFactory::VerifyFactoryCount() { 66 if (kFPFactoryCount != GetFactories()->count()) { 67 SkDebugf("\nExpected %d fragment processor factories, found %d.\n", 68 kFPFactoryCount, GetFactories()->count()); 69 SK_ABORT("Wrong number of fragment processor factories!"); 70 } 71 } 72 73 template <> 74 void GrGeometryProcessorTestFactory::VerifyFactoryCount() { 75 if (kGPFactoryCount != GetFactories()->count()) { 76 SkDebugf("\nExpected %d geometry processor factories, found %d.\n", 77 kGPFactoryCount, GetFactories()->count()); 78 SK_ABORT("Wrong number of geometry processor factories!"); 79 } 80 } 81 82 void GrXPFactoryTestFactory::VerifyFactoryCount() { 83 if (kXPFactoryCount != GetFactories()->count()) { 84 SkDebugf("\nExpected %d xp factory factories, found %d.\n", 85 kXPFactoryCount, GetFactories()->count()); 86 SK_ABORT("Wrong number of xp factory factories!"); 87 } 88 } 89 90 #endif 91 #endif 92 93 94 // We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on 95 // different threads. The GrContext is not used concurrently on different threads and there is a 96 // memory barrier between accesses of a context on different threads. Also, there may be multiple 97 // GrContexts and those contexts may be in use concurrently on different threads. 98 namespace { 99 #if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) 100 static SkSpinlock gProcessorSpinlock; 101 #endif 102 class MemoryPoolAccessor { 103 public: 104 105 // We know in the Android framework there is only one GrContext. 106 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) 107 MemoryPoolAccessor() {} 108 ~MemoryPoolAccessor() {} 109 #else 110 MemoryPoolAccessor() { gProcessorSpinlock.acquire(); } 111 ~MemoryPoolAccessor() { gProcessorSpinlock.release(); } 112 #endif 113 114 GrMemoryPool* pool() const { 115 static GrMemoryPool gPool(4096, 4096); 116 return &gPool; 117 } 118 }; 119 } 120 121 /////////////////////////////////////////////////////////////////////////////// 122 123 void* GrProcessor::operator new(size_t size) { return MemoryPoolAccessor().pool()->allocate(size); } 124 125 void GrProcessor::operator delete(void* target) { 126 return MemoryPoolAccessor().pool()->release(target); 127 } 128