blob: 99833ff96bd05ae706ef1befd8de5d522ab15bb6 [file] [log] [blame]
* 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 "include/private/base/SkTArray.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 <vector>
#include "src/gpu/graphite/PietRenderTask.h"
namespace skgpu::piet {
class Scene;
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 {
static sk_sp<DrawContext> Make(sk_sp<TextureProxy> 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<TextureProxy> targetProxy,
const SkColorInfo& srcColorInfo,
const SkColorInfo& dstColorInfo,
const std::vector<MipLevel>& levels,
const SkIRect& dstRect,
bool recordPietSceneRender(Recorder* recorder,
sk_sp<TextureProxy> targetProxy,
sk_sp<const skgpu::piet::Scene> pietScene);
// 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<Task> 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<Task> snapUploadTask(Recorder*);
sk_sp<Task> snapPietRenderTask(Recorder*);
DrawContext(sk_sp<TextureProxy>, const SkImageInfo&, const SkSurfaceProps&);
sk_sp<TextureProxy> 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<DrawList> fPendingDraws;
// Load and store information for the current pending draws.
LoadOp fPendingLoadOp = LoadOp::kLoad;
StoreOp fPendingStoreOp = StoreOp::kStore;
std::array<float, 4> 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.
SkTArray<std::unique_ptr<DrawPass>> 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<UploadList> fPendingUploads;
std::vector<PietRenderInstance> fPendingPietRenders;
} // namespace skgpu::graphite
#endif // skgpu_graphite_DrawContext_DEFINED