Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2011 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 "GrGLGpu.h"
      9 
     10 #include "builders/GrGLProgramBuilder.h"
     11 #include "GrProcessor.h"
     12 #include "GrProgramDesc.h"
     13 #include "GrGLPathRendering.h"
     14 #include "glsl/GrGLSLFragmentProcessor.h"
     15 #include "glsl/GrGLSLProgramDataManager.h"
     16 #include "SkTSearch.h"
     17 
     18 #ifdef PROGRAM_CACHE_STATS
     19 // Display program cache usage
     20 static const bool c_DisplayCache{false};
     21 #endif
     22 
     23 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
     24 
     25 struct GrGLGpu::ProgramCache::Entry {
     26     Entry(sk_sp<GrGLProgram> program)
     27     : fProgram(std::move(program)) {}
     28 
     29     sk_sp<GrGLProgram> fProgram;
     30 };
     31 
     32 GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu)
     33     : fMap(kMaxEntries)
     34     , fGpu(gpu)
     35 #ifdef PROGRAM_CACHE_STATS
     36     , fTotalRequests(0)
     37     , fCacheMisses(0)
     38     , fHashMisses(0)
     39 #endif
     40 {}
     41 
     42 GrGLGpu::ProgramCache::~ProgramCache() {
     43     // dump stats
     44 #ifdef PROGRAM_CACHE_STATS
     45     if (c_DisplayCache) {
     46         SkDebugf("--- Program Cache ---\n");
     47         SkDebugf("Total requests: %d\n", fTotalRequests);
     48         SkDebugf("Cache misses: %d\n", fCacheMisses);
     49         SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
     50                                             100.f * fCacheMisses / fTotalRequests :
     51                                             0.f);
     52         int cacheHits = fTotalRequests - fCacheMisses;
     53         SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / cacheHits : 0.f);
     54         SkDebugf("---------------------\n");
     55     }
     56 #endif
     57 }
     58 
     59 void GrGLGpu::ProgramCache::abandon() {
     60 #ifdef PROGRAM_CACHE_STATS
     61     fTotalRequests = 0;
     62     fCacheMisses = 0;
     63     fHashMisses = 0;
     64 #endif
     65 }
     66 
     67 GrGLProgram* GrGLGpu::ProgramCache::refProgram(const GrGLGpu* gpu,
     68                                                const GrPipeline& pipeline,
     69                                                const GrPrimitiveProcessor& primProc,
     70                                                bool isPoints) {
     71 #ifdef PROGRAM_CACHE_STATS
     72     ++fTotalRequests;
     73 #endif
     74 
     75     // Get GrGLProgramDesc
     76     GrProgramDesc desc;
     77     if (!GrProgramDesc::Build(&desc, primProc, isPoints, pipeline, *gpu->caps()->shaderCaps())) {
     78         GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n");
     79         return nullptr;
     80     }
     81     desc.finalize();
     82     std::unique_ptr<Entry>* entry = fMap.find(desc);
     83     if (!entry) {
     84         // Didn't find an origin-independent version, check with the specific origin
     85         GrSurfaceOrigin origin = pipeline.proxy()->origin();
     86         desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
     87         desc.finalize();
     88         entry = fMap.find(desc);
     89     }
     90     if (!entry) {
     91         // We have a cache miss
     92 #ifdef PROGRAM_CACHE_STATS
     93         ++fCacheMisses;
     94 #endif
     95         GrGLProgram* program = GrGLProgramBuilder::CreateProgram(pipeline, primProc, &desc, fGpu);
     96         if (nullptr == program) {
     97             return nullptr;
     98         }
     99         entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(sk_sp<GrGLProgram>(program))));
    100     }
    101 
    102     return SkRef((*entry)->fProgram.get());
    103 }
    104