1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h" 9cb93a386Sopenharmony_ci#include "src/core/SkLRUCache.h" 10cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrContextThreadSafeProxyPriv.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrProgramDesc.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 15cb93a386Sopenharmony_ci#include "src/gpu/effects/GrSkSLFP.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci/** 18cb93a386Sopenharmony_ci * The DDL Context is the one in effect during DDL Recording. It isn't backed by a GrGPU and 19cb93a386Sopenharmony_ci * cannot allocate any GPU resources. 20cb93a386Sopenharmony_ci */ 21cb93a386Sopenharmony_ciclass GrDDLContext final : public GrRecordingContext { 22cb93a386Sopenharmony_cipublic: 23cb93a386Sopenharmony_ci GrDDLContext(sk_sp<GrContextThreadSafeProxy> proxy) 24cb93a386Sopenharmony_ci : INHERITED(std::move(proxy), true) { 25cb93a386Sopenharmony_ci } 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci ~GrDDLContext() override {} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci void abandonContext() override { 30cb93a386Sopenharmony_ci SkASSERT(0); // abandoning in a DDL Recorder doesn't make a whole lot of sense 31cb93a386Sopenharmony_ci INHERITED::abandonContext(); 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ciprivate: 35cb93a386Sopenharmony_ci // Add to the set of unique program infos required by this DDL 36cb93a386Sopenharmony_ci void recordProgramInfo(const GrProgramInfo* programInfo) final { 37cb93a386Sopenharmony_ci if (!programInfo) { 38cb93a386Sopenharmony_ci return; 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci const GrCaps* caps = this->caps(); 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci if (this->backend() == GrBackendApi::kMetal || 44cb93a386Sopenharmony_ci this->backend() == GrBackendApi::kDirect3D || 45cb93a386Sopenharmony_ci this->backend() == GrBackendApi::kDawn) { 46cb93a386Sopenharmony_ci // Currently Metal, Direct3D, and Dawn require a live renderTarget to 47cb93a386Sopenharmony_ci // compute the key 48cb93a386Sopenharmony_ci return; 49cb93a386Sopenharmony_ci } 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci GrProgramDesc desc = caps->makeDesc(nullptr, *programInfo); 52cb93a386Sopenharmony_ci if (!desc.isValid()) { 53cb93a386Sopenharmony_ci return; 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci fProgramInfoMap.add(desc, programInfo); 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci void detachProgramData(SkTArray<ProgramData>* dst) final { 60cb93a386Sopenharmony_ci SkASSERT(dst->empty()); 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci fProgramInfoMap.toArray(dst); 63cb93a386Sopenharmony_ci } 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ciprivate: 67cb93a386Sopenharmony_ci class ProgramInfoMap : public ::SkNoncopyable { 68cb93a386Sopenharmony_ci typedef const GrProgramDesc CacheKey; 69cb93a386Sopenharmony_ci typedef const GrProgramInfo* CacheValue; 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci public: 72cb93a386Sopenharmony_ci // All the programInfo data should be stored in the record-time arena so there is no 73cb93a386Sopenharmony_ci // need to ref them here or to delete them in the destructor. 74cb93a386Sopenharmony_ci ProgramInfoMap() : fMap(10) {} 75cb93a386Sopenharmony_ci ~ProgramInfoMap() {} 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci // TODO: this is doing a lot of reallocating of the ProgramDesc! Once the program descs 78cb93a386Sopenharmony_ci // are allocated in the record-time area there won't be a problem. 79cb93a386Sopenharmony_ci void add(CacheKey& desc, const GrProgramInfo* programInfo) { 80cb93a386Sopenharmony_ci SkASSERT(desc.isValid()); 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci const CacheValue* preExisting = fMap.find(desc); 83cb93a386Sopenharmony_ci if (preExisting) { 84cb93a386Sopenharmony_ci return; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci fMap.insert(desc, programInfo); 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci void toArray(SkTArray<ProgramData>* dst) { 91cb93a386Sopenharmony_ci fMap.foreach([dst](CacheKey* programDesc, CacheValue* programInfo) { 92cb93a386Sopenharmony_ci // TODO: remove this allocation once the program descs are stored 93cb93a386Sopenharmony_ci // in the record-time arena. 94cb93a386Sopenharmony_ci dst->emplace_back(std::make_unique<const GrProgramDesc>(*programDesc), 95cb93a386Sopenharmony_ci *programInfo); 96cb93a386Sopenharmony_ci }); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci private: 100cb93a386Sopenharmony_ci struct DescHash { 101cb93a386Sopenharmony_ci uint32_t operator()(CacheKey& desc) const { 102cb93a386Sopenharmony_ci return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci }; 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci SkLRUCache<CacheKey, CacheValue, DescHash> fMap; 107cb93a386Sopenharmony_ci }; 108cb93a386Sopenharmony_ci 109cb93a386Sopenharmony_ci ProgramInfoMap fProgramInfoMap; 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci using INHERITED = GrRecordingContext; 112cb93a386Sopenharmony_ci}; 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_cisk_sp<GrRecordingContext> GrRecordingContextPriv::MakeDDL(sk_sp<GrContextThreadSafeProxy> proxy) { 115cb93a386Sopenharmony_ci sk_sp<GrRecordingContext> context(new GrDDLContext(std::move(proxy))); 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci if (!context->init()) { 118cb93a386Sopenharmony_ci return nullptr; 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci return context; 121cb93a386Sopenharmony_ci} 122