• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrMemoryPool.h"
12 #include "GrSamplerParams.h"
13 #include "GrTexturePriv.h"
14 #include "GrTextureProxy.h"
15 #include "GrXferProcessor.h"
16 #include "SkSpinlock.h"
17 
18 #if GR_TEST_UTILS
19 
resourceProvider()20 GrResourceProvider* GrProcessorTestData::resourceProvider() {
21     return fContext->resourceProvider();
22 }
23 
caps()24 const GrCaps* GrProcessorTestData::caps() {
25     return fContext->caps();
26 }
27 
28 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
29 class GrFragmentProcessor;
30 class GrGeometryProcessor;
31 
32 /*
33  * Originally these were both in the processor unit test header, but then it seemed to cause linker
34  * problems on android.
35  */
36 template<>
37 SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>*
GetFactories()38 GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
39     static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
40     return &gFactories;
41 }
42 
43 template<>
44 SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
GetFactories()45 GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
46     static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories;
47     return &gFactories;
48 }
49 
GetFactories()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 = 42;
61 static const int kGPFactoryCount = 14;
62 static const int kXPFactoryCount = 4;
63 
64 template<>
VerifyFactoryCount()65 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
66     if (kFPFactoryCount != GetFactories()->count()) {
67         SkDebugf("\nExpected %d fragment processor factories, found %d.\n",
68                  kFPFactoryCount, GetFactories()->count());
69         SkFAIL("Wrong number of fragment processor factories!");
70     }
71 }
72 
73 template<>
VerifyFactoryCount()74 void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
75     if (kGPFactoryCount != GetFactories()->count()) {
76         SkDebugf("\nExpected %d geometry processor factories, found %d.\n",
77                  kGPFactoryCount, GetFactories()->count());
78         SkFAIL("Wrong number of geometry processor factories!");
79     }
80 }
81 
VerifyFactoryCount()82 void GrXPFactoryTestFactory::VerifyFactoryCount() {
83     if (kXPFactoryCount != GetFactories()->count()) {
84         SkDebugf("\nExpected %d xp factory factories, found %d.\n",
85                  kXPFactoryCount, GetFactories()->count());
86         SkFAIL("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 static SkSpinlock gProcessorSpinlock;
100 class MemoryPoolAccessor {
101 public:
102 
103 // We know in the Android framework there is only one GrContext.
104 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
MemoryPoolAccessor()105     MemoryPoolAccessor() {}
~MemoryPoolAccessor()106     ~MemoryPoolAccessor() {}
107 #else
108     MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
109     ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
110 #endif
111 
pool() const112     GrMemoryPool* pool() const {
113         static GrMemoryPool gPool(4096, 4096);
114         return &gPool;
115     }
116 };
117 }
118 
119 int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID;
120 
121 ///////////////////////////////////////////////////////////////////////////////
122 
operator new(size_t size)123 void* GrProcessor::operator new(size_t size) { return MemoryPoolAccessor().pool()->allocate(size); }
124 
operator delete(void * target)125 void GrProcessor::operator delete(void* target) {
126     return MemoryPoolAccessor().pool()->release(target);
127 }
128 
129 ///////////////////////////////////////////////////////////////////////////////
130 
addTextureSampler(const TextureSampler * access)131 void GrResourceIOProcessor::addTextureSampler(const TextureSampler* access) {
132     fTextureSamplers.push_back(access);
133 }
134 
addBufferAccess(const BufferAccess * access)135 void GrResourceIOProcessor::addBufferAccess(const BufferAccess* access) {
136     fBufferAccesses.push_back(access);
137 }
138 
addImageStorageAccess(const ImageStorageAccess * access)139 void GrResourceIOProcessor::addImageStorageAccess(const ImageStorageAccess* access) {
140     fImageStorageAccesses.push_back(access);
141 }
142 
addPendingIOs() const143 void GrResourceIOProcessor::addPendingIOs() const {
144     for (const auto& sampler : fTextureSamplers) {
145         sampler->programProxy()->markPendingIO();
146     }
147     for (const auto& buffer : fBufferAccesses) {
148         buffer->programBuffer()->markPendingIO();
149     }
150     for (const auto& imageStorage : fImageStorageAccesses) {
151         imageStorage->programProxy()->markPendingIO();
152     }
153 }
154 
removeRefs() const155 void GrResourceIOProcessor::removeRefs() const {
156     for (const auto& sampler : fTextureSamplers) {
157         sampler->programProxy()->removeRef();
158     }
159     for (const auto& buffer : fBufferAccesses) {
160         buffer->programBuffer()->removeRef();
161     }
162     for (const auto& imageStorage : fImageStorageAccesses) {
163         imageStorage->programProxy()->removeRef();
164     }
165 }
166 
pendingIOComplete() const167 void GrResourceIOProcessor::pendingIOComplete() const {
168     for (const auto& sampler : fTextureSamplers) {
169         sampler->programProxy()->pendingIOComplete();
170     }
171     for (const auto& buffer : fBufferAccesses) {
172         buffer->programBuffer()->pendingIOComplete();
173     }
174     for (const auto& imageStorage : fImageStorageAccesses) {
175         imageStorage->programProxy()->pendingIOComplete();
176     }
177 }
178 
instantiate(GrResourceProvider * resourceProvider) const179 bool GrResourceIOProcessor::instantiate(GrResourceProvider* resourceProvider) const {
180     for (const auto& sampler : fTextureSamplers) {
181         if (!sampler->instantiate(resourceProvider)) {
182             return false;
183         }
184     }
185 
186     // MDB TODO: instantiate 'fBufferAccesses' here as well
187 
188     for (const auto& imageStorage : fImageStorageAccesses) {
189         if (!imageStorage->instantiate(resourceProvider)) {
190             return false;
191         }
192     }
193 
194     return true;
195 }
196 
hasSameSamplersAndAccesses(const GrResourceIOProcessor & that) const197 bool GrResourceIOProcessor::hasSameSamplersAndAccesses(const GrResourceIOProcessor& that) const {
198     if (this->numTextureSamplers() != that.numTextureSamplers() ||
199         this->numBuffers() != that.numBuffers() ||
200         this->numImageStorages() != that.numImageStorages()) {
201         return false;
202     }
203     for (int i = 0; i < this->numTextureSamplers(); ++i) {
204         if (this->textureSampler(i) != that.textureSampler(i)) {
205             return false;
206         }
207     }
208     for (int i = 0; i < this->numBuffers(); ++i) {
209         if (this->bufferAccess(i) != that.bufferAccess(i)) {
210             return false;
211         }
212     }
213     for (int i = 0; i < this->numImageStorages(); ++i) {
214         if (this->imageStorageAccess(i) != that.imageStorageAccess(i)) {
215             return false;
216         }
217     }
218     return true;
219 }
220 
221 ///////////////////////////////////////////////////////////////////////////////////////////////////
222 
TextureSampler()223 GrResourceIOProcessor::TextureSampler::TextureSampler() {}
224 
TextureSampler(sk_sp<GrTextureProxy> proxy,const GrSamplerParams & params)225 GrResourceIOProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
226                                                       const GrSamplerParams& params) {
227     this->reset(std::move(proxy), params);
228 }
229 
TextureSampler(sk_sp<GrTextureProxy> proxy,GrSamplerParams::FilterMode filterMode,SkShader::TileMode tileXAndY,GrShaderFlags visibility)230 GrResourceIOProcessor::TextureSampler::TextureSampler(sk_sp<GrTextureProxy> proxy,
231                                                       GrSamplerParams::FilterMode filterMode,
232                                                       SkShader::TileMode tileXAndY,
233                                                       GrShaderFlags visibility) {
234     this->reset(std::move(proxy), filterMode, tileXAndY, visibility);
235 }
236 
reset(sk_sp<GrTextureProxy> proxy,const GrSamplerParams & params,GrShaderFlags visibility)237 void GrResourceIOProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
238                                                   const GrSamplerParams& params,
239                                                   GrShaderFlags visibility) {
240     fParams = params;
241     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
242     fParams.setFilterMode(SkTMin(params.filterMode(), this->proxy()->highestFilterMode()));
243     fVisibility = visibility;
244 }
245 
reset(sk_sp<GrTextureProxy> proxy,GrSamplerParams::FilterMode filterMode,SkShader::TileMode tileXAndY,GrShaderFlags visibility)246 void GrResourceIOProcessor::TextureSampler::reset(sk_sp<GrTextureProxy> proxy,
247                                                   GrSamplerParams::FilterMode filterMode,
248                                                   SkShader::TileMode tileXAndY,
249                                                   GrShaderFlags visibility) {
250     fProxyRef.setProxy(std::move(proxy), kRead_GrIOType);
251     filterMode = SkTMin(filterMode, this->proxy()->highestFilterMode());
252     fParams.reset(tileXAndY, filterMode);
253     fVisibility = visibility;
254 }
255 
256 ///////////////////////////////////////////////////////////////////////////////////////////////////
257 
ImageStorageAccess(sk_sp<GrTextureProxy> proxy,GrIOType ioType,GrSLMemoryModel memoryModel,GrSLRestrict restrict,GrShaderFlags visibility)258 GrResourceIOProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTextureProxy> proxy,
259                                                               GrIOType ioType,
260                                                               GrSLMemoryModel memoryModel,
261                                                               GrSLRestrict restrict,
262                                                               GrShaderFlags visibility)
263         : fProxyRef(std::move(proxy), ioType) {
264     SkASSERT(fProxyRef.get());
265 
266     fMemoryModel = memoryModel;
267     fRestrict = restrict;
268     fVisibility = visibility;
269     // We currently infer this from the config. However, we could allow the client to specify
270     // a format that is different but compatible with the config.
271     switch (fProxyRef.get()->config()) {
272         case kRGBA_8888_GrPixelConfig:
273             fFormat = GrImageStorageFormat::kRGBA8;
274             break;
275         case kRGBA_8888_sint_GrPixelConfig:
276             fFormat = GrImageStorageFormat::kRGBA8i;
277             break;
278         case kRGBA_half_GrPixelConfig:
279             fFormat = GrImageStorageFormat::kRGBA16f;
280             break;
281         case kRGBA_float_GrPixelConfig:
282             fFormat = GrImageStorageFormat::kRGBA32f;
283             break;
284         default:
285             SkFAIL("Config is not (yet) supported as image storage.");
286             break;
287     }
288 }
289