Home | History | Annotate | Download | only in gpu
      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 "GrCoordTransform.h"
     11 #include "GrGeometryProcessor.h"
     12 #include "GrInvariantOutput.h"
     13 #include "GrMemoryPool.h"
     14 #include "GrXferProcessor.h"
     15 #include "SkSpinlock.h"
     16 
     17 #if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
     18 
     19 class GrFragmentProcessor;
     20 class GrGeometryProcessor;
     21 
     22 /*
     23  * Originally these were both in the processor unit test header, but then it seemed to cause linker
     24  * problems on android.
     25  */
     26 template<>
     27 SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true>*
     28 GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
     29     static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
     30     return &gFactories;
     31 }
     32 
     33 template<>
     34 SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
     35 GrProcessorTestFactory<GrXPFactory>::GetFactories() {
     36     static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
     37     return &gFactories;
     38 }
     39 
     40 template<>
     41 SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
     42 GrProcessorTestFactory<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  */
     52 static const int kFPFactoryCount = 37;
     53 static const int kGPFactoryCount = 14;
     54 static const int kXPFactoryCount = 5;
     55 
     56 template<>
     57 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
     58     if (kFPFactoryCount != GetFactories()->count()) {
     59         SkFAIL("Wrong number of fragment processor factories!");
     60     }
     61 }
     62 
     63 template<>
     64 void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
     65     if (kGPFactoryCount != GetFactories()->count()) {
     66         SkFAIL("Wrong number of geometry processor factories!");
     67     }
     68 }
     69 
     70 template<>
     71 void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() {
     72     if (kXPFactoryCount != GetFactories()->count()) {
     73         SkFAIL("Wrong number of xp factory factories!");
     74     }
     75 }
     76 
     77 #endif
     78 
     79 
     80 // 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
     83 // GrContexts and those contexts may be in use concurrently on different threads.
     84 namespace {
     85 SK_DECLARE_STATIC_SPINLOCK(gProcessorSpinlock);
     86 class MemoryPoolAccessor {
     87 public:
     88     MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
     89 
     90     ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
     91 
     92     GrMemoryPool* pool() const {
     93         static GrMemoryPool gPool(4096, 4096);
     94         return &gPool;
     95     }
     96 };
     97 }
     98 
     99 int32_t GrProcessor::gCurrProcessorClassID = GrProcessor::kIllegalProcessorClassID;
    100 
    101 ///////////////////////////////////////////////////////////////////////////////
    102 
    103 GrProcessor::~GrProcessor() {}
    104 
    105 void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
    106     fTextureAccesses.push_back(access);
    107     this->addGpuResource(access->getProgramTexture());
    108 }
    109 
    110 void* GrProcessor::operator new(size_t size) {
    111     return MemoryPoolAccessor().pool()->allocate(size);
    112 }
    113 
    114 void GrProcessor::operator delete(void* target) {
    115     return MemoryPoolAccessor().pool()->release(target);
    116 }
    117 
    118 bool GrProcessor::hasSameTextureAccesses(const GrProcessor& that) const {
    119     if (this->numTextures() != that.numTextures()) {
    120         return false;
    121     }
    122     for (int i = 0; i < this->numTextures(); ++i) {
    123         if (this->textureAccess(i) != that.textureAccess(i)) {
    124             return false;
    125         }
    126     }
    127     return true;
    128 }
    129 
    130 ///////////////////////////////////////////////////////////////////////////////////////////////////
    131 
    132 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
    133     fCoordTransforms.push_back(transform);
    134     fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet;
    135     SkDEBUGCODE(transform->setInProcessor();)
    136 }
    137 
    138 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
    139     if (fCoordTransforms.count() != that.fCoordTransforms.count()) {
    140         return false;
    141     }
    142     int count = fCoordTransforms.count();
    143     for (int i = 0; i < count; ++i) {
    144         if (*fCoordTransforms[i] != *that.fCoordTransforms[i]) {
    145             return false;
    146         }
    147     }
    148     return true;
    149 }
    150 
    151 void GrFragmentProcessor::computeInvariantOutput(GrInvariantOutput* inout) const {
    152     this->onComputeInvariantOutput(inout);
    153 }
    154 
    155 ///////////////////////////////////////////////////////////////////////////////////////////////////
    156 
    157 // Initial static variable from GrXPFactory
    158 int32_t GrXPFactory::gCurrXPFClassID =
    159         GrXPFactory::kIllegalXPFClassID;
    160