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_Context_DEFINED 9 #define skgpu_graphite_Context_DEFINED 10 11 #include "include/core/SkImage.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkShader.h" 14 #include "include/gpu/graphite/ContextOptions.h" 15 #include "include/gpu/graphite/GraphiteTypes.h" 16 #include "include/gpu/graphite/Recorder.h" 17 #include "include/private/base/SingleOwner.h" 18 19 #include <memory> 20 21 class SkRuntimeEffect; 22 23 namespace skgpu::graphite { 24 25 class BackendTexture; 26 class Buffer; 27 class ClientMappedBufferManager; 28 class Context; 29 class ContextPriv; 30 class GlobalCache; 31 class PaintOptions; 32 class PlotUploadTracker; 33 class QueueManager; 34 class Recording; 35 class ResourceProvider; 36 class SharedContext; 37 class TextureProxy; 38 39 class SK_API Context final { 40 public: 41 Context(const Context&) = delete; 42 Context(Context&&) = delete; 43 Context& operator=(const Context&) = delete; 44 Context& operator=(Context&&) = delete; 45 46 ~Context(); 47 48 BackendApi backend() const; 49 50 std::unique_ptr<Recorder> makeRecorder(const RecorderOptions& = {}); 51 52 bool insertRecording(const InsertRecordingInfo&); 53 bool submit(SyncToCpu = SyncToCpu::kNo); 54 55 void asyncReadPixels(const SkImage* image, 56 const SkColorInfo& dstColorInfo, 57 const SkIRect& srcRect, 58 SkImage::ReadPixelsCallback callback, 59 SkImage::ReadPixelsContext context); 60 61 void asyncReadPixels(const SkSurface* surface, 62 const SkColorInfo& dstColorInfo, 63 const SkIRect& srcRect, 64 SkImage::ReadPixelsCallback callback, 65 SkImage::ReadPixelsContext context); 66 67 /** 68 * Checks whether any asynchronous work is complete and if so calls related callbacks. 69 */ 70 void checkAsyncWorkCompletion(); 71 72 /** 73 * Called to delete the passed in BackendTexture. This should only be called if the 74 * BackendTexture was created by calling Recorder::createBackendTexture on a Recorder created 75 * from this Context. If the BackendTexture is not valid or does not match the BackendApi of the 76 * Context then nothing happens. 77 * 78 * Otherwise this will delete/release the backend object that is wrapped in the BackendTexture. 79 * The BackendTexture will be reset to an invalid state and should not be used again. 80 */ 81 void deleteBackendTexture(BackendTexture&); 82 83 // Provides access to functions that aren't part of the public API. 84 ContextPriv priv(); 85 const ContextPriv priv() const; // NOLINT(readability-const-return-type) 86 87 class ContextID { 88 public: 89 static Context::ContextID Next(); 90 ContextID()91 ContextID() : fID(SK_InvalidUniqueID) {} 92 93 bool operator==(const ContextID& that) const { return fID == that.fID; } 94 bool operator!=(const ContextID& that) const { return !(*this == that); } 95 makeInvalid()96 void makeInvalid() { fID = SK_InvalidUniqueID; } isValid()97 bool isValid() const { return fID != SK_InvalidUniqueID; } 98 99 private: ContextID(uint32_t id)100 constexpr ContextID(uint32_t id) : fID(id) {} 101 uint32_t fID; 102 }; 103 contextID()104 ContextID contextID() const { return fContextID; } 105 106 protected: 107 Context(sk_sp<SharedContext>, std::unique_ptr<QueueManager>, const ContextOptions&); 108 109 private: 110 friend class ContextPriv; 111 friend class ContextCtorAccessor; 112 singleOwner()113 SingleOwner* singleOwner() const { return &fSingleOwner; } 114 115 // Must be called in Make() to handle one-time GPU setup operations that can possibly fail and 116 // require Context::Make() to return a nullptr. 117 bool finishInitialization(); 118 119 void asyncReadPixels(const TextureProxy* textureProxy, 120 const SkImageInfo& srcImageInfo, 121 const SkColorInfo& dstColorInfo, 122 const SkIRect& srcRect, 123 SkImage::ReadPixelsCallback callback, 124 SkImage::ReadPixelsContext context); 125 126 // Inserts a texture to buffer transfer task, used by asyncReadPixels methods 127 struct PixelTransferResult { 128 using ConversionFn = void(void* dst, const void* mappedBuffer); 129 // If null then the transfer could not be performed. Otherwise this buffer will contain 130 // the pixel data when the transfer is complete. 131 sk_sp<Buffer> fTransferBuffer; 132 // If this is null then the transfer buffer will contain the data in the requested 133 // color type. Otherwise, when the transfer is done this must be called to convert 134 // from the transfer buffer's color type to the requested color type. 135 std::function<ConversionFn> fPixelConverter; 136 }; 137 PixelTransferResult transferPixels(const TextureProxy*, 138 const SkImageInfo& srcImageInfo, 139 const SkColorInfo& dstColorInfo, 140 const SkIRect& srcRect); 141 142 sk_sp<SharedContext> fSharedContext; 143 std::unique_ptr<ResourceProvider> fResourceProvider; 144 std::unique_ptr<QueueManager> fQueueManager; 145 std::unique_ptr<ClientMappedBufferManager> fMappedBufferManager; 146 std::unique_ptr<PlotUploadTracker> fPlotUploadTracker; 147 148 // In debug builds we guard against improper thread handling. This guard is passed to the 149 // ResourceCache for the Context. 150 mutable SingleOwner fSingleOwner; 151 152 #if GRAPHITE_TEST_UTILS 153 // In test builds a Recorder may track the Context that was used to create it. 154 bool fStoreContextRefInRecorder = false; 155 // If this tracking is on, to allow the client to safely delete this Context or its Recorders 156 // in any order we must also track the Recorders created here. 157 std::vector<Recorder*> fTrackedRecorders; 158 #endif 159 160 // Needed for MessageBox handling 161 const ContextID fContextID; 162 }; 163 164 } // namespace skgpu::graphite 165 166 #endif // skgpu_graphite_Context_DEFINED 167