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