1 /* 2 * Copyright 2019 Google Inc. 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 GrContextThreadSafeProxy_DEFINED 9 #define GrContextThreadSafeProxy_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkTypes.h" 13 #include "include/gpu/GpuTypes.h" 14 #include "include/gpu/ganesh/GrContextOptions.h" 15 #include "include/gpu/ganesh/GrTypes.h" 16 17 #include <atomic> 18 #include <cstddef> 19 #include <cstdint> 20 #include <memory> 21 22 class GrBackendFormat; 23 class GrCaps; 24 class GrContextThreadSafeProxyPriv; 25 class GrSurfaceCharacterization; 26 class GrThreadSafeCache; 27 class GrThreadSafePipelineBuilder; 28 class SkSurfaceProps; 29 enum SkColorType : int; 30 enum class SkTextureCompressionType; 31 struct SkImageInfo; 32 33 namespace sktext::gpu { class TextBlobRedrawCoordinator; } 34 35 /** 36 * Can be used to perform actions related to the generating GrContext in a thread safe manner. The 37 * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. 38 */ 39 class SK_API GrContextThreadSafeProxy : public SkNVRefCnt<GrContextThreadSafeProxy> { 40 public: 41 virtual ~GrContextThreadSafeProxy(); 42 43 /** 44 * Create a surface characterization for a DDL that will be replayed into the GrContext 45 * that created this proxy. On failure the resulting characterization will be invalid (i.e., 46 * "!c.isValid()"). 47 * 48 * @param cacheMaxResourceBytes The max resource bytes limit that will be in effect 49 * when the DDL created with this characterization is 50 * replayed. 51 * Note: the contract here is that the DDL will be 52 * created as if it had a full 'cacheMaxResourceBytes' 53 * to use. If replayed into a GrContext that already has 54 * locked GPU memory, the replay can exceed the budget. 55 * To rephrase, all resource allocation decisions are 56 * made at record time and at playback time the budget 57 * limits will be ignored. 58 * @param ii The image info specifying properties of the SkSurface 59 * that the DDL created with this characterization will 60 * be replayed into. 61 * Note: Ganesh doesn't make use of the SkImageInfo's 62 * alphaType 63 * @param backendFormat Information about the format of the GPU surface that 64 * will back the SkSurface upon replay 65 * @param sampleCount The sample count of the SkSurface that the DDL 66 * created with this characterization will be replayed 67 * into 68 * @param origin The origin of the SkSurface that the DDL created with 69 * this characterization will be replayed into 70 * @param surfaceProps The surface properties of the SkSurface that the DDL 71 * created with this characterization will be replayed 72 * into 73 * @param isMipmapped Will the surface the DDL will be replayed into have 74 * space allocated for mipmaps? 75 * @param willUseGLFBO0 Will the surface the DDL will be replayed into be 76 * backed by GL FBO 0. This flag is only valid if using 77 * an GL backend. 78 * @param isTextureable Will the surface be able to act as a texture? 79 * @param isProtected Will the (Vulkan) surface be DRM protected? 80 * @param vkRTSupportsInputAttachment Can the vulkan surface be used as in input 81 attachment? 82 * @param forVulkanSecondaryCommandBuffer Will the surface be wrapping a vulkan secondary 83 * command buffer via a GrVkSecondaryCBDrawContext? If 84 * this is true then the following is required: 85 * isTexureable = false 86 * isMipmapped = false 87 * willUseGLFBO0 = false 88 * vkRTSupportsInputAttachment = false 89 */ 90 GrSurfaceCharacterization createCharacterization( 91 size_t cacheMaxResourceBytes, 92 const SkImageInfo& ii, 93 const GrBackendFormat& backendFormat, 94 int sampleCount, 95 GrSurfaceOrigin origin, 96 const SkSurfaceProps& surfaceProps, 97 skgpu::Mipmapped isMipmapped, 98 bool willUseGLFBO0 = false, 99 bool isTextureable = true, 100 skgpu::Protected isProtected = GrProtected::kNo, 101 bool vkRTSupportsInputAttachment = false, 102 bool forVulkanSecondaryCommandBuffer = false); 103 104 /* 105 * Retrieve the default GrBackendFormat for a given SkColorType and renderability. 106 * It is guaranteed that this backend format will be the one used by the following 107 * SkColorType and GrSurfaceCharacterization-based createBackendTexture methods. 108 * 109 * The caller should check that the returned format is valid. 110 */ 111 GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const; 112 113 /** 114 * Retrieve the GrBackendFormat for a given SkTextureCompressionType. This is 115 * guaranteed to match the backend format used by the following 116 * createCompressedBackendTexture methods that take a CompressionType. 117 * 118 * The caller should check that the returned format is valid. 119 */ 120 GrBackendFormat compressedBackendFormat(SkTextureCompressionType c) const; 121 122 /** 123 * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA 124 * rendering is supported for the color type. 0 is returned if rendering to this color type 125 * is not supported at all. 126 */ 127 int maxSurfaceSampleCountForColorType(SkColorType colorType) const; 128 isValid()129 bool isValid() const { return nullptr != fCaps; } 130 131 bool operator==(const GrContextThreadSafeProxy& that) const { 132 // Each GrContext should only ever have a single thread-safe proxy. 133 SkASSERT((this == &that) == (this->fContextID == that.fContextID)); 134 return this == &that; 135 } 136 137 bool operator!=(const GrContextThreadSafeProxy& that) const { return !(*this == that); } 138 139 // Provides access to functions that aren't part of the public API. 140 GrContextThreadSafeProxyPriv priv(); 141 const GrContextThreadSafeProxyPriv priv() const; // NOLINT(readability-const-return-type) 142 143 protected: 144 // DDL TODO: need to add unit tests for backend & maybe options 145 GrContextThreadSafeProxy(GrBackendApi, const GrContextOptions&); 146 147 private: 148 friend class GrContextThreadSafeProxyPriv; // for ctor and hidden methods 149 150 void abandonContext(); 151 bool abandoned() const; 152 153 // TODO: This should be part of the constructor but right now we have a chicken-and-egg problem 154 // with GrContext where we get the caps by creating a GPU which requires a context (see the 155 // `init` method on GrContext_Base). 156 void init(sk_sp<const GrCaps>, sk_sp<GrThreadSafePipelineBuilder>); 157 158 virtual bool isValidCharacterizationForVulkan(sk_sp<const GrCaps>, 159 bool isTextureable, 160 skgpu::Mipmapped isMipmapped, 161 skgpu::Protected isProtected, 162 bool vkRTSupportsInputAttachment, 163 bool forVulkanSecondaryCommandBuffer); 164 165 const GrBackendApi fBackend; 166 const GrContextOptions fOptions; 167 const uint32_t fContextID; 168 sk_sp<const GrCaps> fCaps; 169 std::unique_ptr<sktext::gpu::TextBlobRedrawCoordinator> fTextBlobRedrawCoordinator; 170 std::unique_ptr<GrThreadSafeCache> fThreadSafeCache; 171 sk_sp<GrThreadSafePipelineBuilder> fPipelineBuilder; 172 std::atomic<bool> fAbandoned{false}; 173 }; 174 175 #endif 176