GrProcessor.cpp revision ff343074b2a3fdaa5f120600e28717e366bceadd
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 "GrBackendProcessorFactory.h" 10#include "GrContext.h" 11#include "GrCoordTransform.h" 12#include "GrMemoryPool.h" 13#include "SkTLS.h" 14 15#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 16 17/* 18 * Originally these were both in the processor unit test header, but then it seemed to cause linker 19 * problems on android. 20 */ 21template<> 22SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>* 23GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() { 24 static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories; 25 return &gFactories; 26} 27 28template<> 29SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>* 30GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() { 31 static SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true> gFactories; 32 return &gFactories; 33} 34 35/* 36 * To ensure we always have successful static initialization, before creating from the factories 37 * we verify the count is as expected. If a new factory is added, then these numbers must be 38 * manually adjusted. 39 */ 40static const int kFPFactoryCount = 37; 41static const int kGPFactoryCount = 14; 42 43template<> 44void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() { 45 if (kFPFactoryCount != GetFactories()->count()) { 46 SkFAIL("Wrong number of fragment processor factories!"); 47 } 48} 49 50template<> 51void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() { 52 if (kGPFactoryCount != GetFactories()->count()) { 53 SkFAIL("Wrong number of geometry processor factories!"); 54 } 55} 56 57#endif 58 59namespace GrProcessorUnitTest { 60const SkMatrix& TestMatrix(SkRandom* random) { 61 static SkMatrix gMatrices[5]; 62 static bool gOnce; 63 if (!gOnce) { 64 gMatrices[0].reset(); 65 gMatrices[1].setTranslate(SkIntToScalar(-100), SkIntToScalar(100)); 66 gMatrices[2].setRotate(SkIntToScalar(17)); 67 gMatrices[3].setRotate(SkIntToScalar(185)); 68 gMatrices[3].postTranslate(SkIntToScalar(66), SkIntToScalar(-33)); 69 gMatrices[3].postScale(SkIntToScalar(2), SK_ScalarHalf); 70 gMatrices[4].setRotate(SkIntToScalar(215)); 71 gMatrices[4].set(SkMatrix::kMPersp0, 0.00013f); 72 gMatrices[4].set(SkMatrix::kMPersp1, -0.000039f); 73 gOnce = true; 74 } 75 return gMatrices[random->nextULessThan(static_cast<uint32_t>(SK_ARRAY_COUNT(gMatrices)))]; 76} 77} 78 79class GrProcessor_Globals { 80public: 81 static GrMemoryPool* GetTLS() { 82 return (GrMemoryPool*)SkTLS::Get(CreateTLS, DeleteTLS); 83 } 84 85private: 86 static void* CreateTLS() { 87 return SkNEW_ARGS(GrMemoryPool, (4096, 4096)); 88 } 89 90 static void DeleteTLS(void* pool) { 91 SkDELETE(reinterpret_cast<GrMemoryPool*>(pool)); 92 } 93}; 94 95int32_t GrBackendProcessorFactory::fCurrProcessorClassID = 96 GrBackendProcessorFactory::kIllegalProcessorClassID; 97 98/////////////////////////////////////////////////////////////////////////////// 99 100GrProcessor::~GrProcessor() {} 101 102const char* GrProcessor::name() const { 103 return this->getFactory().name(); 104} 105 106void GrProcessor::addTextureAccess(const GrTextureAccess* access) { 107 fTextureAccesses.push_back(access); 108 this->addGpuResource(access->getProgramTexture()); 109} 110 111void* GrProcessor::operator new(size_t size) { 112 return GrProcessor_Globals::GetTLS()->allocate(size); 113} 114 115void GrProcessor::operator delete(void* target) { 116 GrProcessor_Globals::GetTLS()->release(target); 117} 118 119bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const { 120 if (this->numTextures() != that.numTextures()) { 121 return false; 122 } 123 for (int i = 0; i < this->numTextures(); ++i) { 124 if (this->textureAccess(i) != that.textureAccess(i)) { 125 return false; 126 } 127 } 128 return true; 129} 130 131#ifdef SK_DEBUG 132 133void GrProcessor::InvariantOutput::validate() const { 134 if (fIsSingleComponent) { 135 SkASSERT(0 == fValidFlags || kRGBA_GrColorComponentFlags == fValidFlags); 136 if (kRGBA_GrColorComponentFlags == fValidFlags) { 137 SkASSERT(this->colorComponentsAllEqual()); 138 } 139 } 140 141 SkASSERT(this->validPreMulColor()); 142 143 // If we claim that we are not using the input color we must not be modulating the input. 144 SkASSERT(fNonMulStageFound || fWillUseInputColor); 145} 146 147bool GrProcessor::InvariantOutput::colorComponentsAllEqual() const { 148 unsigned colorA = GrColorUnpackA(fColor); 149 return(GrColorUnpackR(fColor) == colorA && 150 GrColorUnpackG(fColor) == colorA && 151 GrColorUnpackB(fColor) == colorA); 152} 153 154bool GrProcessor::InvariantOutput::validPreMulColor() const { 155 if (kA_GrColorComponentFlag & fValidFlags) { 156 float c[4]; 157 GrColorToRGBAFloat(fColor, c); 158 if (kR_GrColorComponentFlag & fValidFlags) { 159 if (c[0] > c[3]) { 160 return false; 161 } 162 } 163 if (kG_GrColorComponentFlag & fValidFlags) { 164 if (c[1] > c[3]) { 165 return false; 166 } 167 } 168 if (kB_GrColorComponentFlag & fValidFlags) { 169 if (c[2] > c[3]) { 170 return false; 171 } 172 } 173 } 174 return true; 175} 176#endif // end DEBUG 177 178/////////////////////////////////////////////////////////////////////////////////////////////////// 179 180void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { 181 fCoordTransforms.push_back(transform); 182 SkDEBUGCODE(transform->setInProcessor();) 183} 184 185bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { 186 if (fCoordTransforms.count() != that.fCoordTransforms.count()) { 187 return false; 188 } 189 int count = fCoordTransforms.count(); 190 for (int i = 0; i < count; ++i) { 191 if (*fCoordTransforms[i] != *that.fCoordTransforms[i]) { 192 return false; 193 } 194 } 195 return true; 196} 197