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 "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>*
     27 GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
     28     static SkTArray<GrProcessorTestFactory<GrFragmentProcessor>*, true> gFactories;
     29     return &gFactories;
     30 }
     31 
     32 template<>
     33 SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
     34 GrProcessorTestFactory<GrXPFactory>::GetFactories() {
     35     static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
     36     return &gFactories;
     37 }
     38 
     39 template<>
     40 SkTArray<GrProcessorTestFactory<GrGeometryProcessor>*, true>*
     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<>
     56 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
     57     if (kFPFactoryCount != GetFactories()->count()) {
     58         SkFAIL("Wrong number of fragment processor factories!");
     59     }
     60 }
     61 
     62 template<>
     63 void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
     64     if (kGPFactoryCount != GetFactories()->count()) {
     65         SkFAIL("Wrong number of geometry processor factories!");
     66     }
     67 }
     68 
     69 template<>
     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:
     87     MemoryPoolAccessor() { gProcessorSpinlock.acquire(); }
     88 
     89     ~MemoryPoolAccessor() { gProcessorSpinlock.release(); }
     90 
     91     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 
    102 GrProcessor::~GrProcessor() {}
    103 
    104 void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
    105     fTextureAccesses.push_back(access);
    106     this->addGpuResource(access->getProgramTexture());
    107 }
    108 
    109 void* GrProcessor::operator new(size_t size) {
    110     return MemoryPoolAccessor().pool()->allocate(size);
    111 }
    112 
    113 void GrProcessor::operator delete(void* target) {
    114     return MemoryPoolAccessor().pool()->release(target);
    115 }
    116 
    117 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