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 = 8;
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 SK_DECLARE_STATIC_SPINLOCK(gProcessorSpinlock);
85 class MemoryPoolAccessor {
86 public:
MemoryPoolAccessor()87 MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
88
~MemoryPoolAccessor()89 ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
90
pool() const91 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
~GrProcessor()102 GrProcessor::~GrProcessor() {}
103
addTextureAccess(const GrTextureAccess * access)104 void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
105 fTextureAccesses.push_back(access);
106 this->addGpuResource(access->getProgramTexture());
107 }
108
operator new(size_t size)109 void* GrProcessor::operator new(size_t size) {
110 return MemoryPoolAccessor().pool()->allocate(size);
111 }
112
operator delete(void * target)113 void GrProcessor::operator delete(void* target) {
114 return MemoryPoolAccessor().pool()->release(target);
115 }
116
hasSameTextureAccesses(const GrProcessor & that) const117 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