1 /* 2 * Copyright 2021 Google LLC 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 #ifndef skgpu_graphite_DrawContext_DEFINED 9 #define skgpu_graphite_DrawContext_DEFINED 10 11 #include "include/core/SkImageInfo.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkSurfaceProps.h" 14 #include "include/private/base/SkTArray.h" 15 16 #include "src/gpu/graphite/DrawList.h" 17 #include "src/gpu/graphite/DrawOrder.h" 18 #include "src/gpu/graphite/DrawTypes.h" 19 #include "src/gpu/graphite/ResourceTypes.h" 20 #include "src/gpu/graphite/TextureProxyView.h" 21 #include "src/gpu/graphite/task/UploadTask.h" 22 23 #include <vector> 24 25 class SkPixmap; 26 27 namespace skgpu::graphite { 28 29 class Geometry; 30 class Recorder; 31 class Transform; 32 33 class Caps; 34 class ComputePathAtlas; 35 class DrawTask; 36 class PathAtlas; 37 class Task; 38 class TextureProxy; 39 40 /** 41 * DrawContext records draw commands into a specific Surface, via a general task graph 42 * representing GPU work and their inter-dependencies. 43 */ 44 class DrawContext final : public SkRefCnt { 45 public: 46 static sk_sp<DrawContext> Make(const Caps* caps, 47 sk_sp<TextureProxy> target, 48 SkISize deviceSize, 49 const SkColorInfo&, 50 const SkSurfaceProps&); 51 52 ~DrawContext() override; 53 imageInfo()54 const SkImageInfo& imageInfo() const { return fImageInfo; } colorInfo()55 const SkColorInfo& colorInfo() const { return fImageInfo.colorInfo(); } target()56 TextureProxy* target() { return fTarget.get(); } target()57 const TextureProxy* target() const { return fTarget.get(); } refTarget()58 sk_sp<TextureProxy> refTarget() const { return fTarget; } 59 60 // May be null if the target is not texturable. readSurfaceView()61 const TextureProxyView& readSurfaceView() const { return fReadView; } 62 surfaceProps()63 const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; } 64 pendingRenderSteps()65 int pendingRenderSteps() const { return fPendingDraws->renderStepCount(); } 66 67 void clear(const SkColor4f& clearColor); 68 void discard(); 69 70 void recordDraw(const Renderer* renderer, 71 const Transform& localToDevice, 72 const Geometry& geometry, 73 const Clip& clip, 74 DrawOrder ordering, 75 const PaintParams* paint, 76 const StrokeStyle* stroke); 77 78 bool recordUpload(Recorder* recorder, 79 sk_sp<TextureProxy> targetProxy, 80 const SkColorInfo& srcColorInfo, 81 const SkColorInfo& dstColorInfo, 82 const std::vector<MipLevel>& levels, 83 const SkIRect& dstRect, 84 std::unique_ptr<ConditionalUploadContext>); 85 86 // Add a Task that will be executed *before* any of the pending draws and uploads are 87 // executed as part of the next flush(). Dependency 88 void recordDependency(sk_sp<Task>); 89 90 // Returns the transient path atlas that uses compute to accumulate coverage masks for atlas 91 // draws recorded to this SDC. The atlas gets created lazily upon request. Returns nullptr 92 // if compute path generation is not supported. 93 PathAtlas* getComputePathAtlas(Recorder*); 94 95 // Moves all accumulated pending recorded operations (draws and uploads), and any other 96 // dependent tasks into the DrawTask currently being built. 97 void flush(Recorder*); 98 99 // Flushes (if needed) and completes the current DrawTask, returning it to the caller. 100 // Subsequent recorded operations will be added to a new DrawTask. 101 sk_sp<Task> snapDrawTask(Recorder*); 102 103 private: 104 DrawContext(const Caps*, sk_sp<TextureProxy>, const SkImageInfo&, const SkSurfaceProps&); 105 106 sk_sp<TextureProxy> fTarget; 107 TextureProxyView fReadView; 108 SkImageInfo fImageInfo; 109 const SkSurfaceProps fSurfaceProps; 110 111 // The in-progress DrawTask that will be snapped and returned when some external requirement 112 // must depend on the contents of this DrawContext's target. As higher-level Skia operations 113 // are recorded, it can be necessary to flush pending draws and uploads into the task list. 114 // This provides a place to reset scratch textures or buffers as their previous state will have 115 // been consumed by the flushed tasks rendering to this DrawContext's target. 116 sk_sp<DrawTask> fCurrentDrawTask; 117 118 // Stores the most immediately recorded draws and uploads into the DrawContext's target. These 119 // are collected outside of the DrawTask so that encoder switches can be minimized when 120 // flushing. 121 std::unique_ptr<DrawList> fPendingDraws; 122 std::unique_ptr<UploadList> fPendingUploads; 123 // Load and store information for the current pending draws. 124 LoadOp fPendingLoadOp = LoadOp::kLoad; 125 StoreOp fPendingStoreOp = StoreOp::kStore; 126 std::array<float, 4> fPendingClearColor = { 0, 0, 0, 0 }; 127 128 // Accumulates atlas coverage masks generated by compute dispatches that are required by one or 129 // more entries in `fPendingDraws`. When pending draws are snapped into a new DrawPass, a 130 // compute dispatch group gets recorded which schedules the accumulated masks to get drawn into 131 // an atlas texture. The accumulated masks are then cleared which frees up the atlas for 132 // future draws. 133 // 134 // TODO: Currently every PathAtlas contains a single texture. If multiple snapped draw 135 // passes resulted in multiple ComputePathAtlas dispatch groups, the later dispatches would 136 // overwrite the atlas texture since all compute tasks are scheduled before render tasks. This 137 // is currently not an issue since there is only one DrawPass per flush but we may want to 138 // either support one atlas texture per DrawPass or record the dispatches once per 139 // RenderPassTask rather than DrawPass. 140 std::unique_ptr<ComputePathAtlas> fComputePathAtlas; 141 }; 142 143 } // namespace skgpu::graphite 144 145 #endif // skgpu_graphite_DrawContext_DEFINED 146