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>*
GetFactories()27 GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
28 static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
29 return &gFactories;
30 }
31
32 template<>
33 SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
GetFactories()34 GrProcessorTestFactory<GrXPFactory>::GetFactories() {
35 static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
36 return &gFactories;
37 }
38
39 template<>
40 SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
GetFactories()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 = 6;
54
55 template<>
VerifyFactoryCount()56 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
57 if (kFPFactoryCount != GetFactories()->count()) {
58 SkFAIL("Wrong number of fragment processor factories!");
59 }
60 }
61
62 template<>
VerifyFactoryCount()63 void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
64 if (kGPFactoryCount != GetFactories()->count()) {
65 SkFAIL("Wrong number of geometry processor factories!");
66 }
67 }
68
69 template<>
VerifyFactoryCount()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 static SkSpinlock gProcessorSpinlock;
85 class MemoryPoolAccessor {
86 public:
87
88 // We know in the Android framework there is only one GrContext.
89 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
MemoryPoolAccessor()90 MemoryPoolAccessor() {}
~MemoryPoolAccessor()91 ~MemoryPoolAccessor() {}
92 #else
93 MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
94 ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
95 #endif
96
pool() const97 GrMemoryPool* pool() const {
98 static GrMemoryPool gPool(4096, 4096);
99 return &gPool;
100 }
101 };
102 }
103
104 int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID;
105
106 ///////////////////////////////////////////////////////////////////////////////
107
~GrProcessor()108 GrProcessor::~GrProcessor() {}
109
addTextureAccess(const GrTextureAccess * access)110 void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
111 fTextureAccesses.push_back(access);
112 this->addGpuResource(access->getProgramTexture());
113 }
114
addBufferAccess(const GrBufferAccess * access)115 void GrProcessor::addBufferAccess(const GrBufferAccess* access) {
116 fBufferAccesses.push_back(access);
117 this->addGpuResource(access->getProgramBuffer());
118 }
119
operator new(size_t size)120 void* GrProcessor::operator new(size_t size) {
121 return MemoryPoolAccessor().pool()->allocate(size);
122 }
123
operator delete(void * target)124 void GrProcessor::operator delete(void* target) {
125 return MemoryPoolAccessor().pool()->release(target);
126 }
127
hasSameSamplers(const GrProcessor & that) const128 bool GrProcessor::hasSameSamplers(const GrProcessor& that) const {
129 if (this->numTextures() != that.numTextures() || this->numBuffers() != that.numBuffers()) {
130 return false;
131 }
132 for (int i = 0; i < this->numTextures(); ++i) {
133 if (this->textureAccess(i) != that.textureAccess(i)) {
134 return false;
135 }
136 }
137 for (int i = 0; i < this->numBuffers(); ++i) {
138 if (this->bufferAccess(i) != that.bufferAccess(i)) {
139 return false;
140 }
141 }
142 return true;
143 }
144
145 ///////////////////////////////////////////////////////////////////////////////////////////////////
146
147 // Initial static variable from GrXPFactory
148 int32_t GrXPFactory::gCurrXPFClassID =
149 GrXPFactory::kIllegalXPFClassID;
150