1 /* 2 * Copyright 2022 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_UploadTask_DEFINED 9 #define skgpu_graphite_UploadTask_DEFINED 10 11 #include "src/gpu/graphite/Task.h" 12 13 #include <memory> 14 #include <vector> 15 16 #include "include/core/SkImageInfo.h" 17 #include "include/core/SkRect.h" 18 #include "include/core/SkRefCnt.h" 19 20 namespace skgpu::graphite { 21 22 class Buffer; 23 struct BufferTextureCopyData; 24 class Recorder; 25 class TextureProxy; 26 27 struct MipLevel { 28 const void* fPixels = nullptr; 29 size_t fRowBytes = 0; 30 }; 31 32 /** 33 * The ConditionalUploadContext, if set, is used to determine whether an upload needs to occur 34 * on Recording playback. Clients will need to create their own subclasses to store the 35 * necessary data and override the needsUpload() method to do this check. 36 */ 37 class ConditionalUploadContext { 38 public: ~ConditionalUploadContext()39 virtual ~ConditionalUploadContext() {} 40 41 virtual bool needsUpload(Context*) const = 0; 42 }; 43 44 /** 45 * An UploadInstance represents a single set of uploads from a buffer to texture that 46 * can be processed in a single command. 47 */ 48 class UploadInstance { 49 public: 50 static UploadInstance Make(Recorder*, 51 sk_sp<TextureProxy> targetProxy, 52 const SkColorInfo& srcColorInfo, 53 const SkColorInfo& dstColorInfo, 54 const std::vector<MipLevel>& levels, 55 const SkIRect& dstRect, 56 std::unique_ptr<ConditionalUploadContext>); 57 isValid()58 bool isValid() const { return fBuffer != nullptr; } 59 60 bool prepareResources(ResourceProvider*); 61 62 // Adds upload command to the given CommandBuffer 63 void addCommand(Context*, CommandBuffer*, Task::ReplayTargetData) const; 64 65 private: UploadInstance()66 UploadInstance() {} 67 UploadInstance(const Buffer*, 68 size_t bytesPerPixel, 69 sk_sp<TextureProxy>, 70 std::vector<BufferTextureCopyData>, 71 std::unique_ptr<ConditionalUploadContext>); 72 73 const Buffer* fBuffer; 74 size_t fBytesPerPixel; 75 sk_sp<TextureProxy> fTextureProxy; 76 std::vector<BufferTextureCopyData> fCopyData; 77 std::unique_ptr<ConditionalUploadContext> fConditionalContext; 78 }; 79 80 /** 81 * An UploadList is a mutable collection of UploadCommands. 82 * 83 * Currently commands are accumulated in order and processed in the same order. Dependency 84 * management is expected to be handled by the TaskGraph. 85 * 86 * When an upload is appended to the list its data will be copied to a Buffer in 87 * preparation for a deferred upload. 88 */ 89 class UploadList { 90 public: 91 bool recordUpload(Recorder*, 92 sk_sp<TextureProxy> targetProxy, 93 const SkColorInfo& srcColorInfo, 94 const SkColorInfo& dstColorInfo, 95 const std::vector<MipLevel>& levels, 96 const SkIRect& dstRect, 97 std::unique_ptr<ConditionalUploadContext>); 98 size()99 int size() { return fInstances.size(); } 100 101 private: 102 friend class UploadTask; 103 104 std::vector<UploadInstance> fInstances; 105 }; 106 107 /* 108 * An UploadTask is a immutable collection of UploadCommands. 109 * 110 * When adding commands to the commandBuffer the texture proxies in those 111 * commands will be instantiated and the copy command added. 112 */ 113 class UploadTask final : public Task { 114 public: 115 static sk_sp<UploadTask> Make(UploadList*); 116 static sk_sp<UploadTask> Make(UploadInstance); 117 118 ~UploadTask() override; 119 120 bool prepareResources(ResourceProvider*, const RuntimeEffectDictionary*) override; 121 122 bool addCommands(Context*, CommandBuffer*, ReplayTargetData) override; 123 124 private: 125 UploadTask(std::vector<UploadInstance>); 126 UploadTask(UploadInstance); 127 128 std::vector<UploadInstance> fInstances; 129 }; 130 131 } // namespace skgpu::graphite 132 133 #endif // skgpu_graphite_UploadTask_DEFINED 134