/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef skgpu_graphite_DrawContext_DEFINED #define skgpu_graphite_DrawContext_DEFINED #include "include/core/SkImageInfo.h" #include "include/core/SkRefCnt.h" #include "include/core/SkSurfaceProps.h" #include "src/gpu/graphite/AttachmentTypes.h" #include "src/gpu/graphite/DrawList.h" #include "src/gpu/graphite/DrawOrder.h" #include "src/gpu/graphite/DrawTypes.h" #include "src/gpu/graphite/UploadTask.h" #include #ifdef SK_ENABLE_PIET_GPU #include "src/gpu/graphite/PietRenderTask.h" namespace skgpu::piet { class Scene; } #endif class SkPixmap; namespace skgpu::graphite { class Geometry; class Recorder; class Transform; class AtlasManager; class Caps; class DrawPass; class Task; class TextureProxy; class TextureProxyView; /** * DrawContext records draw commands into a specific Surface, via a general task graph * representing GPU work and their inter-dependencies. */ class DrawContext final : public SkRefCnt { public: static sk_sp Make(sk_sp target, SkISize deviceSize, const SkColorInfo&, const SkSurfaceProps&); ~DrawContext() override; const SkImageInfo& imageInfo() const { return fImageInfo; } const SkColorInfo& colorInfo() const { return fImageInfo.colorInfo(); } TextureProxy* target() { return fTarget.get(); } const TextureProxy* target() const { return fTarget.get(); } TextureProxyView readSurfaceView(const Caps*); const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } int pendingDrawCount() const { return fPendingDraws->drawCount(); } void clear(const SkColor4f& clearColor); void recordDraw(const Renderer* renderer, const Transform& localToDevice, const Geometry& geometry, const Clip& clip, DrawOrder ordering, const PaintParams* paint, const StrokeStyle* stroke); bool recordTextUploads(AtlasManager*); bool recordUpload(Recorder* recorder, sk_sp targetProxy, const SkColorInfo& srcColorInfo, const SkColorInfo& dstColorInfo, const std::vector& levels, const SkIRect& dstRect, std::unique_ptr); #ifdef SK_ENABLE_PIET_GPU bool recordPietSceneRender(Recorder* recorder, sk_sp targetProxy, sk_sp pietScene); #endif // Ends the current DrawList being accumulated by the SDC, converting it into an optimized and // immutable DrawPass. The DrawPass will be ordered after any other snapped DrawPasses or // appended DrawPasses from a child SDC. A new DrawList is started to record subsequent drawing // operations. // // TBD - Should this take a special occluder list to filter the DrawList? // TBD - should this also return the task so the caller can point to it with its own // dependencies? Or will that be mostly automatic based on draws and proxy refs? void snapDrawPass(Recorder*); // TBD: snapRenderPassTask() might not need to be public, and could be spec'ed to require that // snapDrawPass() must have been called first. A lot of it will depend on how the task graph is // managed. // Ends the current DrawList if needed, as in 'snapDrawPass', and moves the new DrawPass and all // prior accumulated DrawPasses into a RenderPassTask that can be drawn and depended on. The // caller is responsible for configuring the returned Tasks's dependencies. // // Returns null if there are no pending commands or draw passes to move into a task. sk_sp snapRenderPassTask(Recorder*); // Ends the current UploadList if needed, and moves the accumulated Uploads into an UploadTask // that can be drawn and depended on. The caller is responsible for configuring the returned // Tasks's dependencies. // // Returns null if there are no pending uploads to move into a task. // // TODO: see if we can merge transfers into this sk_sp snapUploadTask(Recorder*); #ifdef SK_ENABLE_PIET_GPU sk_sp snapPietRenderTask(Recorder*); #endif private: DrawContext(sk_sp, const SkImageInfo&, const SkSurfaceProps&); sk_sp fTarget; SkImageInfo fImageInfo; const SkSurfaceProps fSurfaceProps; // Stores the most immediately recorded draws into the SDC's surface. This list is mutable and // can be appended to, or have its commands rewritten if they are inlined into a parent SDC. std::unique_ptr fPendingDraws; // Load and store information for the current pending draws. LoadOp fPendingLoadOp = LoadOp::kLoad; StoreOp fPendingStoreOp = StoreOp::kStore; std::array fPendingClearColor = { 0, 0, 0, 0 }; // Stores previously snapped DrawPasses of this DC, or inlined child DCs whose content // couldn't have been copied directly to fPendingDraws. While each DrawPass is immutable, the // list of DrawPasses is not final until there is an external dependency on the SDC's content // that requires it to be resolved as its own render pass (vs. inlining the SDC's passes into a // parent's render pass). // TODO: It will be easier to debug/understand the DrawPass structure of a context if // consecutive DrawPasses to the same target are stored in a DrawPassChain. A DrawContext with // multiple DrawPassChains is then clearly accumulating subpasses across multiple targets. std::vector> fDrawPasses; // Stores the most immediately recorded uploads into Textures. This list is mutable and // can be appended to, or have its commands rewritten if they are inlined into a parent DC. std::unique_ptr fPendingUploads; #ifdef SK_ENABLE_PIET_GPU std::vector fPendingPietRenders; #endif }; } // namespace skgpu::graphite #endif // skgpu_graphite_DrawContext_DEFINED