/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkDeferredDisplayList_DEFINED #define SkDeferredDisplayList_DEFINED #include "include/core/SkRefCnt.h" #include "include/core/SkSurfaceCharacterization.h" #include "include/core/SkTypes.h" class SkDeferredDisplayListPriv; #if SK_SUPPORT_GPU #include "include/private/GrRecordingContext.h" #include "include/private/SkTArray.h" #include class GrRenderTask; class GrRenderTargetProxy; struct GrCCPerOpsTaskPaths; #endif /* * This class contains pre-processed gpu operations that can be replayed into * an SkSurface via SkSurface::draw(SkDeferredDisplayList*). */ class SkDeferredDisplayList { public: SK_API ~SkDeferredDisplayList(); SK_API const SkSurfaceCharacterization& characterization() const { return fCharacterization; } #if SK_SUPPORT_GPU /** * Iterate through the programs required by the DDL. */ class SK_API ProgramIterator { public: ProgramIterator(GrContext*, SkDeferredDisplayList*); ~ProgramIterator(); // This returns true if any work was done. Getting a cache hit does not count as work. bool compile(); bool done() const; void next(); private: GrContext* fContext; const SkTArray& fProgramData; int fIndex; }; #endif // Provides access to functions that aren't part of the public API. SkDeferredDisplayListPriv priv(); const SkDeferredDisplayListPriv priv() const; private: friend class GrDrawingManager; // for access to 'fRenderTasks', 'fLazyProxyData', 'fArenas' friend class SkDeferredDisplayListRecorder; // for access to 'fLazyProxyData' friend class SkDeferredDisplayListPriv; // This object is the source from which the lazy proxy backing the DDL will pull its backing // texture when the DDL is replayed. It has to be separately ref counted bc the lazy proxy // can outlive the DDL. class LazyProxyData : public SkRefCnt { #if SK_SUPPORT_GPU public: // Upon being replayed - this field will be filled in (by the DrawingManager) with the // proxy backing the destination SkSurface. Note that, since there is no good place to // clear it, it can become a dangling pointer. Additionally, since the renderTargetProxy // doesn't get a ref here, the SkSurface that owns it must remain alive until the DDL // is flushed. // TODO: the drawing manager could ref the renderTargetProxy for the DDL and then add // a renderingTask to unref it after the DDL's ops have been executed. GrRenderTargetProxy* fReplayDest = nullptr; #endif }; SK_API SkDeferredDisplayList(const SkSurfaceCharacterization& characterization, sk_sp); #if SK_SUPPORT_GPU const SkTArray& programData() const { return fProgramData; } #endif const SkSurfaceCharacterization fCharacterization; #if SK_SUPPORT_GPU // This needs to match the same type in GrCoverageCountingPathRenderer.h using PendingPathsMap = std::map>; // When programs are stored in 'fProgramData' their memory is actually allocated in // 'fArenas.fRecordTimeAllocator'. In that case that arena must be freed before // 'fPendingPaths' which relies on uniquely holding the atlas proxies used by the // GrCCClipPaths. PendingPathsMap fPendingPaths; // This is the path data from CCPR. // These are ordered such that the destructor cleans op tasks up first (which may refer back // to the arena and memory pool in their destructors). GrRecordingContext::OwnedArenas fArenas; SkTArray> fRenderTasks; SkTArray fProgramData; sk_sp fLazyProxyData; #endif }; #endif