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