blob: 39c55a60e4d12ed26f11eacd861dc502f3ecf56b [file] [log] [blame]
tomhudson@google.com168e6342012-04-18 17:49:20 +00001/*
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
joshualittb0a8a372014-09-23 09:50:21 -07008#include "GrProcessor.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +00009#include "GrContext.h"
bsalomon@google.com77af6802013-10-02 13:04:56 +000010#include "GrCoordTransform.h"
joshualitt2e3b3e32014-12-09 13:31:14 -080011#include "GrGeometryProcessor.h"
egdaniel605dd0f2014-11-12 08:35:25 -080012#include "GrInvariantOutput.h"
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000013#include "GrMemoryPool.h"
egdaniel915187b2014-12-05 12:58:28 -080014#include "GrXferProcessor.h"
joshualitt23ac62c2015-03-30 09:53:47 -070015#include "SkSpinlock.h"
tomhudson@google.com168e6342012-04-18 17:49:20 +000016
joshualitt9e87fa72014-10-09 13:12:35 -070017#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
18
joshualitteb2a6762014-12-04 11:35:33 -080019class GrFragmentProcessor;
20class GrGeometryProcessor;
21
joshualitt9e87fa72014-10-09 13:12:35 -070022/*
23 * Originally these were both in the processor unit test header, but then it seemed to cause linker
24 * problems on android.
25 */
26template<>
27SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>*
28GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
29 static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
30 return &gFactories;
31}
32
33template<>
egdanielc2304142014-12-11 13:15:13 -080034SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
35GrProcessorTestFactory<GrXPFactory>::GetFactories() {
36 static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
egdaniel378092f2014-12-03 10:40:13 -080037 return &gFactories;
38}
39
40template<>
joshualitt9e87fa72014-10-09 13:12:35 -070041SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
42GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
43 static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories;
44 return &gFactories;
45}
46
47/*
48 * To ensure we always have successful static initialization, before creating from the factories
49 * we verify the count is as expected. If a new factory is added, then these numbers must be
50 * manually adjusted.
51 */
reed71a6cbf2015-05-04 08:32:51 -070052static const int kFPFactoryCount = 37;
joshualitt4973d9d2014-11-08 09:24:25 -080053static const int kGPFactoryCount = 14;
egdaniel54f0e9d2015-01-16 06:29:47 -080054static const int kXPFactoryCount = 5;
joshualitt9e87fa72014-10-09 13:12:35 -070055
56template<>
57void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
58 if (kFPFactoryCount != GetFactories()->count()) {
59 SkFAIL("Wrong number of fragment processor factories!");
60 }
61}
62
63template<>
64void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
65 if (kGPFactoryCount != GetFactories()->count()) {
66 SkFAIL("Wrong number of geometry processor factories!");
67 }
68}
69
egdaniel378092f2014-12-03 10:40:13 -080070template<>
egdanielc2304142014-12-11 13:15:13 -080071void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() {
egdaniel378092f2014-12-03 10:40:13 -080072 if (kXPFactoryCount != GetFactories()->count()) {
egdanielc2304142014-12-11 13:15:13 -080073 SkFAIL("Wrong number of xp factory factories!");
egdaniel378092f2014-12-03 10:40:13 -080074 }
75}
76
joshualitt9e87fa72014-10-09 13:12:35 -070077#endif
78
bsalomon5baedd62015-03-09 12:15:53 -070079
joshualitt23ac62c2015-03-30 09:53:47 -070080// We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on
81// different threads. The GrContext is not used concurrently on different threads and there is a
82// memory barrier between accesses of a context on different threads. Also, there may be multiple
bsalomon5baedd62015-03-09 12:15:53 -070083// GrContexts and those contexts may be in use concurrently on different threads.
84namespace {
joshualitt23ac62c2015-03-30 09:53:47 -070085SK_DECLARE_STATIC_SPINLOCK(gProcessorSpinlock);
bsalomon5baedd62015-03-09 12:15:53 -070086class MemoryPoolAccessor {
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000087public:
joshualitt23ac62c2015-03-30 09:53:47 -070088 MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000089
joshualitt23ac62c2015-03-30 09:53:47 -070090 ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000091
bsalomon5baedd62015-03-09 12:15:53 -070092 GrMemoryPool* pool() const {
93 static GrMemoryPool gPool(4096, 4096);
94 return &gPool;
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000095 }
96};
bsalomon5baedd62015-03-09 12:15:53 -070097}
tomhudson@google.comdcba4c22012-07-24 21:36:16 +000098
bsalomon5baedd62015-03-09 12:15:53 -070099int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID;
tomhudson@google.com168e6342012-04-18 17:49:20 +0000100
bsalomon@google.com0ac6af42013-01-16 15:16:18 +0000101///////////////////////////////////////////////////////////////////////////////
102
joshualittb0a8a372014-09-23 09:50:21 -0700103GrProcessor::~GrProcessor() {}
tomhudson@google.com168e6342012-04-18 17:49:20 +0000104
joshualittb0a8a372014-09-23 09:50:21 -0700105void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
bsalomon@google.com50db75c2013-01-11 13:54:30 +0000106 fTextureAccesses.push_back(access);
bsalomonf96ba022014-09-17 08:05:40 -0700107 this->addGpuResource(access->getProgramTexture());
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000108}
109
joshualittb0a8a372014-09-23 09:50:21 -0700110void* GrProcessor::operator new(size_t size) {
bsalomon5baedd62015-03-09 12:15:53 -0700111 return MemoryPoolAccessor().pool()->allocate(size);
tomhudson@google.comdcba4c22012-07-24 21:36:16 +0000112}
113
joshualittb0a8a372014-09-23 09:50:21 -0700114void GrProcessor::operator delete(void* target) {
bsalomon5baedd62015-03-09 12:15:53 -0700115 return MemoryPoolAccessor().pool()->release(target);
tomhudson@google.comdcba4c22012-07-24 21:36:16 +0000116}
bsalomon@google.com77af6802013-10-02 13:04:56 +0000117
bsalomon420d7e92014-10-16 09:18:09 -0700118bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
119 if (this->numTextures() != that.numTextures()) {
120 return false;
bsalomon@google.com77af6802013-10-02 13:04:56 +0000121 }
bsalomon420d7e92014-10-16 09:18:09 -0700122 for (int i = 0; i < this->numTextures(); ++i) {
123 if (this->textureAccess(i) != that.textureAccess(i)) {
124 return false;
125 }
126 }
127 return true;
bsalomon@google.com77af6802013-10-02 13:04:56 +0000128}
egdaniel1a8ecdf2014-10-03 06:24:12 -0700129
joshualitta5305a12014-10-10 17:47:00 -0700130///////////////////////////////////////////////////////////////////////////////////////////////////
131
132void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
133 fCoordTransforms.push_back(transform);
joshualitt290c09b2014-12-19 13:45:20 -0800134 fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet;
bsalomonf2765412014-10-15 18:34:46 -0700135 SkDEBUGCODE(transform->setInProcessor();)
joshualitta5305a12014-10-10 17:47:00 -0700136}
bsalomonde258cd2014-10-15 19:06:21 -0700137
wangyix58d890b2015-08-12 09:40:47 -0700138int GrFragmentProcessor::registerChildProcessor(const GrFragmentProcessor* child) {
139 // Append the child's transforms to our transforms array and the child's textures array to our
140 // textures array
141 if (!child->fCoordTransforms.empty()) {
142 fCoordTransforms.push_back_n(child->fCoordTransforms.count(),
143 child->fCoordTransforms.begin());
144 }
145 if (!child->fTextureAccesses.empty()) {
146 fTextureAccesses.push_back_n(child->fTextureAccesses.count(),
147 child->fTextureAccesses.begin());
148 }
149
150 int index = fChildProcessors.count();
151 fChildProcessors.push_back(GrFragmentStage(child));
152
wangyix7ef45a12015-08-13 06:51:35 -0700153 if (child->willReadFragmentPosition()) {
wangyix58d890b2015-08-12 09:40:47 -0700154 this->setWillReadFragmentPosition();
wangyix7ef45a12015-08-13 06:51:35 -0700155 }
wangyix58d890b2015-08-12 09:40:47 -0700156
157 return index;
wangyix4b3050b2015-08-04 07:59:37 -0700158}
159
bsalomonde258cd2014-10-15 19:06:21 -0700160bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
wangyix58d890b2015-08-12 09:40:47 -0700161 if (this->numTransforms() != that.numTransforms()) {
bsalomonde258cd2014-10-15 19:06:21 -0700162 return false;
163 }
wangyix58d890b2015-08-12 09:40:47 -0700164 int count = this->numTransforms();
bsalomonde258cd2014-10-15 19:06:21 -0700165 for (int i = 0; i < count; ++i) {
wangyix58d890b2015-08-12 09:40:47 -0700166 if (this->coordTransform(i) != that.coordTransform(i)) {
bsalomonde258cd2014-10-15 19:06:21 -0700167 return false;
168 }
169 }
170 return true;
171}
joshualittc07379d2014-11-20 14:50:39 -0800172
joshualitt56995b52014-12-11 15:44:02 -0800173void GrFragmentProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
174 this->onComputeInvariantOutput(inout);
175}
176
joshualittc07379d2014-11-20 14:50:39 -0800177///////////////////////////////////////////////////////////////////////////////////////////////////
178
egdaniel915187b2014-12-05 12:58:28 -0800179// Initial static variable from GrXPFactory
180int32_t GrXPFactory::gCurrXPFClassID =
181 GrXPFactory::kIllegalXPFClassID;
joshualitt5b4f05f2015-07-10 07:26:21 -0700182
183///////////////////////////////////////////////////////////////////////////////////////////////////
184
185// GrProcessorDataManager lives in the same pool
186void* GrProcessorDataManager::operator new(size_t size) {
187 return MemoryPoolAccessor().pool()->allocate(size);
188}
189
190void GrProcessorDataManager::operator delete(void* target) {
191 return MemoryPoolAccessor().pool()->release(target);
192}