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 "GrGeometryProcessor.h" 11 #include "GrInvariantOutput.h" 12 #include "GrMemoryPool.h" 13 #include "GrXferProcessor.h" 14 #include "SkSpinlock.h" 15 16 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 17 18 class GrFragmentProcessor; 19 class GrGeometryProcessor; 20 21 /* 22 * Originally these were both in the processor unit test header, but then it seemed to cause linker 23 * problems on android. 24 */ 25 template<> 26 SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>* 27 GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() { 28 static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories; 29 return &gFactories; 30 } 31 32 template<> 33 SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>* 34 GrProcessorTestFactory<GrXPFactory>::GetFactories() { 35 static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories; 36 return &gFactories; 37 } 38 39 template<> 40 SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>* 41 GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() { 42 static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories; 43 return &gFactories; 44 } 45 46 /* 47 * To ensure we always have successful static initialization, before creating from the factories 48 * we verify the count is as expected. If a new factory is added, then these numbers must be 49 * manually adjusted. 50 */ 51 static const int kFPFactoryCount = 41; 52 static const int kGPFactoryCount = 14; 53 static const int kXPFactoryCount = 8; 54 55 template<> 56 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() { 57 if (kFPFactoryCount != GetFactories()->count()) { 58 SkFAIL("Wrong number of fragment processor factories!"); 59 } 60 } 61 62 template<> 63 void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() { 64 if (kGPFactoryCount != GetFactories()->count()) { 65 SkFAIL("Wrong number of geometry processor factories!"); 66 } 67 } 68 69 template<> 70 void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() { 71 if (kXPFactoryCount != GetFactories()->count()) { 72 SkFAIL("Wrong number of xp factory factories!"); 73 } 74 } 75 76 #endif 77 78 79 // We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on 80 // different threads. The GrContext is not used concurrently on different threads and there is a 81 // memory barrier between accesses of a context on different threads. Also, there may be multiple 82 // GrContexts and those contexts may be in use concurrently on different threads. 83 namespace { 84 SK_DECLARE_STATIC_SPINLOCK(gProcessorSpinlock); 85 class MemoryPoolAccessor { 86 public: 87 MemoryPoolAccessor() { gProcessorSpinlock.acquire(); } 88 89 ~MemoryPoolAccessor() { gProcessorSpinlock.release(); } 90 91 GrMemoryPool* pool() const { 92 static GrMemoryPool gPool(4096, 4096); 93 return &gPool; 94 } 95 }; 96 } 97 98 int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID; 99 100 /////////////////////////////////////////////////////////////////////////////// 101 102 GrProcessor::~GrProcessor() {} 103 104 void GrProcessor::addTextureAccess(const GrTextureAccess* access) { 105 fTextureAccesses.push_back(access); 106 this->addGpuResource(access->getProgramTexture()); 107 } 108 109 void* GrProcessor::operator new(size_t size) { 110 return MemoryPoolAccessor().pool()->allocate(size); 111 } 112 113 void GrProcessor::operator delete(void* target) { 114 return MemoryPoolAccessor().pool()->release(target); 115 } 116 117 bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const { 118 if (this->numTextures() != that.numTextures()) { 119 return false; 120 } 121 for (int i = 0; i < this->numTextures(); ++i) { 122 if (this->textureAccess(i) != that.textureAccess(i)) { 123 return false; 124 } 125 } 126 return true; 127 } 128 129 /////////////////////////////////////////////////////////////////////////////////////////////////// 130 131 // Initial static variable from GrXPFactory 132 int32_t GrXPFactory::gCurrXPFClassID = 133 GrXPFactory::kIllegalXPFClassID; 134