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) : fProgram(std::move(program)) {}
     27 
     28     sk_sp<GrGLProgram> fProgram;
     29 };
     30 
     31 GrGLGpu::ProgramCache::ProgramCache(GrGLGpu* gpu)
     32     : fMap(kMaxEntries)
     33     , fGpu(gpu)
     34 #ifdef PROGRAM_CACHE_STATS
     35     , fTotalRequests(0)
     36     , fCacheMisses(0)
     37     , fHashMisses(0)
     38 #endif
     39 {}
     40 
     41 GrGLGpu::ProgramCache::~ProgramCache() {
     42     // dump stats
     43 #ifdef PROGRAM_CACHE_STATS
     44     if (c_DisplayCache) {
     45         SkDebugf("--- Program Cache ---\n");
     46         SkDebugf("Total requests: %d\n", fTotalRequests);
     47         SkDebugf("Cache misses: %d\n", fCacheMisses);
     48         SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0) ?
     49                                             100.f * fCacheMisses / fTotalRequests :
     50                                             0.f);
     51         int cacheHits = fTotalRequests - fCacheMisses;
     52         SkDebugf("Hash miss %%: %f\n", (cacheHits > 0) ? 100.f * fHashMisses / cacheHits : 0.f);
     53         SkDebugf("---------------------\n");
     54     }
     55 #endif
     56 }
     57 
     58 void GrGLGpu::ProgramCache::abandon() {
     59 #ifdef PROGRAM_CACHE_STATS
     60     fTotalRequests = 0;
     61     fCacheMisses = 0;
     62     fHashMisses = 0;
     63 #endif
     64 
     65     fMap.foreach([](std::unique_ptr<Entry>* e) {
     66         (*e)->fProgram->abandon();
     67     });
     68     fMap.reset();
     69 }
     70 
     71 GrGLProgram* GrGLGpu::ProgramCache::refProgram(GrGLGpu* gpu,
     72                                                GrRenderTarget* renderTarget,
     73                                                GrSurfaceOrigin origin,
     74                                                const GrPrimitiveProcessor& primProc,
     75                                                const GrTextureProxy* const primProcProxies[],
     76                                                const GrPipeline& pipeline,
     77                                                bool isPoints) {
     78 #ifdef PROGRAM_CACHE_STATS
     79     ++fTotalRequests;
     80 #endif
     81 
     82     // Get GrGLProgramDesc
     83     GrProgramDesc desc;
     84     if (!GrProgramDesc::Build(&desc, renderTarget, primProc, isPoints, pipeline, gpu)) {
     85         GrCapsDebugf(gpu->caps(), "Failed to gl program descriptor!\n");
     86         return nullptr;
     87     }
     88     std::unique_ptr<Entry>* entry = fMap.find(desc);
     89     if (!entry) {
     90         // Didn't find an origin-independent version, check with the specific origin
     91         desc.setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(origin));
     92         entry = fMap.find(desc);
     93     }
     94     if (!entry) {
     95         // We have a cache miss
     96 #ifdef PROGRAM_CACHE_STATS
     97         ++fCacheMisses;
     98 #endif
     99         GrGLProgram* program = GrGLProgramBuilder::CreateProgram(renderTarget, origin,
    100                                                                  primProc, primProcProxies,
    101                                                                  pipeline, &desc, fGpu);
    102         if (nullptr == program) {
    103             return nullptr;
    104         }
    105         entry = fMap.insert(desc, std::unique_ptr<Entry>(new Entry(sk_sp<GrGLProgram>(program))));
    106     }
    107 
    108     return SkRef((*entry)->fProgram.get());
    109 }
    110