Line data Source code
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 :
20 0 : GrResourceProvider* GrProcessorTestData::resourceProvider() {
21 0 : return fContext->resourceProvider();
22 : }
23 :
24 0 : const GrCaps* GrProcessorTestData::caps() {
25 0 : 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>*
38 : GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
39 : static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
40 : return &gFactories;
41 : }
42 :
43 : template<>
44 : SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
45 : GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
46 : static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, 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 = 41;
61 : static const int kGPFactoryCount = 14;
62 : static const int kXPFactoryCount = 4;
63 :
64 : template<>
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<>
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 :
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)
105 : MemoryPoolAccessor() {}
106 : ~MemoryPoolAccessor() {}
107 : #else
108 0 : MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
109 0 : ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
110 : #endif
111 :
112 0 : GrMemoryPool* pool() const {
113 0 : static GrMemoryPool gPool(4096, 4096);
114 0 : return &gPool;
115 : }
116 : };
117 : }
118 :
119 : int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID;
120 :
121 : ///////////////////////////////////////////////////////////////////////////////
122 :
123 0 : void* GrProcessor::operator new(size_t size) { return MemoryPoolAccessor().pool()->allocate(size); }
124 :
125 0 : void GrProcessor::operator delete(void* target) {
126 0 : return MemoryPoolAccessor().pool()->release(target);
127 : }
128 :
129 : ///////////////////////////////////////////////////////////////////////////////
130 :
131 0 : void GrResourceIOProcessor::addTextureSampler(const TextureSampler* access) {
132 0 : fTextureSamplers.push_back(access);
133 0 : }
134 :
135 0 : void GrResourceIOProcessor::addBufferAccess(const BufferAccess* access) {
136 0 : fBufferAccesses.push_back(access);
137 0 : }
138 :
139 0 : void GrResourceIOProcessor::addImageStorageAccess(const ImageStorageAccess* access) {
140 0 : fImageStorageAccesses.push_back(access);
141 0 : }
142 :
143 0 : void GrResourceIOProcessor::addPendingIOs() const {
144 0 : for (const auto& sampler : fTextureSamplers) {
145 0 : sampler->programTexture()->markPendingIO();
146 : }
147 0 : for (const auto& buffer : fBufferAccesses) {
148 0 : buffer->programBuffer()->markPendingIO();
149 : }
150 0 : for (const auto& imageStorage : fImageStorageAccesses) {
151 0 : imageStorage->programTexture()->markPendingIO();
152 : }
153 0 : }
154 :
155 0 : void GrResourceIOProcessor::removeRefs() const {
156 0 : for (const auto& sampler : fTextureSamplers) {
157 0 : sampler->programTexture()->removeRef();
158 : }
159 0 : for (const auto& buffer : fBufferAccesses) {
160 0 : buffer->programBuffer()->removeRef();
161 : }
162 0 : for (const auto& imageStorage : fImageStorageAccesses) {
163 0 : imageStorage->programTexture()->removeRef();
164 : }
165 0 : }
166 :
167 0 : void GrResourceIOProcessor::pendingIOComplete() const {
168 0 : for (const auto& sampler : fTextureSamplers) {
169 0 : sampler->programTexture()->pendingIOComplete();
170 : }
171 0 : for (const auto& buffer : fBufferAccesses) {
172 0 : buffer->programBuffer()->pendingIOComplete();
173 : }
174 0 : for (const auto& imageStorage : fImageStorageAccesses) {
175 0 : imageStorage->programTexture()->pendingIOComplete();
176 : }
177 0 : }
178 :
179 0 : bool GrResourceIOProcessor::hasSameSamplersAndAccesses(const GrResourceIOProcessor& that) const {
180 0 : if (this->numTextureSamplers() != that.numTextureSamplers() ||
181 0 : this->numBuffers() != that.numBuffers() ||
182 0 : this->numImageStorages() != that.numImageStorages()) {
183 0 : return false;
184 : }
185 0 : for (int i = 0; i < this->numTextureSamplers(); ++i) {
186 0 : if (this->textureSampler(i) != that.textureSampler(i)) {
187 0 : return false;
188 : }
189 : }
190 0 : for (int i = 0; i < this->numBuffers(); ++i) {
191 0 : if (this->bufferAccess(i) != that.bufferAccess(i)) {
192 0 : return false;
193 : }
194 : }
195 0 : for (int i = 0; i < this->numImageStorages(); ++i) {
196 0 : if (this->imageStorageAccess(i) != that.imageStorageAccess(i)) {
197 0 : return false;
198 : }
199 : }
200 0 : return true;
201 : }
202 :
203 : ///////////////////////////////////////////////////////////////////////////////////////////////////
204 :
205 0 : GrResourceIOProcessor::TextureSampler::TextureSampler() {}
206 :
207 0 : GrResourceIOProcessor::TextureSampler::TextureSampler(GrTexture* texture,
208 0 : const GrSamplerParams& params) {
209 0 : this->reset(texture, params);
210 0 : }
211 :
212 0 : GrResourceIOProcessor::TextureSampler::TextureSampler(GrTexture* texture,
213 : GrSamplerParams::FilterMode filterMode,
214 : SkShader::TileMode tileXAndY,
215 0 : GrShaderFlags visibility) {
216 0 : this->reset(texture, filterMode, tileXAndY, visibility);
217 0 : }
218 :
219 0 : GrResourceIOProcessor::TextureSampler::TextureSampler(GrResourceProvider* resourceProvider,
220 : sk_sp<GrTextureProxy> proxy,
221 0 : const GrSamplerParams& params) {
222 0 : this->reset(resourceProvider, std::move(proxy), params);
223 0 : }
224 :
225 0 : GrResourceIOProcessor::TextureSampler::TextureSampler(GrResourceProvider* resourceProvider,
226 : sk_sp<GrTextureProxy> proxy,
227 : GrSamplerParams::FilterMode filterMode,
228 : SkShader::TileMode tileXAndY,
229 0 : GrShaderFlags visibility) {
230 0 : this->reset(resourceProvider, std::move(proxy), filterMode, tileXAndY, visibility);
231 0 : }
232 :
233 0 : void GrResourceIOProcessor::TextureSampler::reset(GrTexture* texture,
234 : const GrSamplerParams& params,
235 : GrShaderFlags visibility) {
236 0 : SkASSERT(texture);
237 0 : fTexture.set(SkRef(texture), kRead_GrIOType);
238 0 : fParams = params;
239 0 : fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode()));
240 0 : fVisibility = visibility;
241 0 : }
242 :
243 0 : void GrResourceIOProcessor::TextureSampler::reset(GrTexture* texture,
244 : GrSamplerParams::FilterMode filterMode,
245 : SkShader::TileMode tileXAndY,
246 : GrShaderFlags visibility) {
247 0 : SkASSERT(texture);
248 0 : fTexture.set(SkRef(texture), kRead_GrIOType);
249 0 : filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode());
250 0 : fParams.reset(tileXAndY, filterMode);
251 0 : fVisibility = visibility;
252 0 : }
253 :
254 0 : void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourceProvider,
255 : sk_sp<GrTextureProxy> proxy,
256 : const GrSamplerParams& params,
257 : GrShaderFlags visibility) {
258 : // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
259 : // to taking a GrSurfaceProxy just use the IORefs on the proxy
260 0 : GrTexture* texture = proxy->instantiate(resourceProvider);
261 0 : SkASSERT(texture);
262 0 : fTexture.set(SkRef(texture), kRead_GrIOType);
263 0 : fParams = params;
264 0 : fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode()));
265 0 : fVisibility = visibility;
266 0 : }
267 :
268 0 : void GrResourceIOProcessor::TextureSampler::reset(GrResourceProvider* resourceProvider,
269 : sk_sp<GrTextureProxy> proxy,
270 : GrSamplerParams::FilterMode filterMode,
271 : SkShader::TileMode tileXAndY,
272 : GrShaderFlags visibility) {
273 : // For now, end the deferral at this time. Once all the TextureSamplers are swapped over
274 : // to taking a GrSurfaceProxy just use the IORefs on the proxy
275 0 : GrTexture* texture = proxy->instantiate(resourceProvider);
276 0 : SkASSERT(texture);
277 0 : fTexture.set(SkRef(texture), kRead_GrIOType);
278 0 : filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode());
279 0 : fParams.reset(tileXAndY, filterMode);
280 0 : fVisibility = visibility;
281 0 : }
282 :
283 : ///////////////////////////////////////////////////////////////////////////////////////////////////
284 :
285 0 : GrResourceIOProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture,
286 : GrIOType ioType,
287 : GrSLMemoryModel memoryModel,
288 : GrSLRestrict restrict,
289 0 : GrShaderFlags visibility) {
290 0 : SkASSERT(texture);
291 0 : fTexture.set(texture.release(), ioType);
292 0 : fMemoryModel = memoryModel;
293 0 : fRestrict = restrict;
294 0 : fVisibility = visibility;
295 : // We currently infer this from the config. However, we could allow the client to specify
296 : // a format that is different but compatible with the config.
297 0 : switch (fTexture.get()->config()) {
298 : case kRGBA_8888_GrPixelConfig:
299 0 : fFormat = GrImageStorageFormat::kRGBA8;
300 0 : break;
301 : case kRGBA_8888_sint_GrPixelConfig:
302 0 : fFormat = GrImageStorageFormat::kRGBA8i;
303 0 : break;
304 : case kRGBA_half_GrPixelConfig:
305 0 : fFormat = GrImageStorageFormat::kRGBA16f;
306 0 : break;
307 : case kRGBA_float_GrPixelConfig:
308 0 : fFormat = GrImageStorageFormat::kRGBA32f;
309 0 : break;
310 : default:
311 0 : SkFAIL("Config is not (yet) supported as image storage.");
312 0 : break;
313 : }
314 0 : }
|