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 SK_SUPPORT_GPU 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 GrTextBlobCache; 25 class GrThreadSafeCache; 26 class GrThreadSafePipelineBuilder; 27 class SkSurfaceCharacterization; 28 class SkSurfaceProps; 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 final : public SkNVRefCnt<GrContextThreadSafeProxy> { 35 public: 36 ~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 SkSurfaceCharacterization createCharacterization( 86 size_t cacheMaxResourceBytes, 87 const SkImageInfo& ii, 88 const GrBackendFormat& backendFormat, 89 int sampleCount, 90 GrSurfaceOrigin origin, 91 const SkSurfaceProps& surfaceProps, 92 bool isMipMapped, 93 bool willUseGLFBO0 = false, 94 bool isTextureable = true, 95 GrProtected 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 SkSurfaceCharacterization-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 SkImage::CompressionType. 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(SkImage::CompressionType c) const; 116 isValid()117 bool isValid() const { return nullptr != fCaps; } 118 119 bool operator==(const GrContextThreadSafeProxy& that) const { 120 // Each GrContext should only ever have a single thread-safe proxy. 121 SkASSERT((this == &that) == (this->fContextID == that.fContextID)); 122 return this == &that; 123 } 124 125 bool operator!=(const GrContextThreadSafeProxy& that) const { return !(*this == that); } 126 127 // Provides access to functions that aren't part of the public API. 128 GrContextThreadSafeProxyPriv priv(); 129 const GrContextThreadSafeProxyPriv priv() const; // NOLINT(readability-const-return-type) 130 131 private: 132 friend class GrContextThreadSafeProxyPriv; // for ctor and hidden methods 133 134 // DDL TODO: need to add unit tests for backend & maybe options 135 GrContextThreadSafeProxy(GrBackendApi, const GrContextOptions&); 136 137 void abandonContext(); 138 bool abandoned() const; 139 140 // TODO: This should be part of the constructor but right now we have a chicken-and-egg problem 141 // with GrContext where we get the caps by creating a GPU which requires a context (see the 142 // `init` method on GrContext_Base). 143 void init(sk_sp<const GrCaps>, sk_sp<GrThreadSafePipelineBuilder>); 144 145 const GrBackendApi fBackend; 146 const GrContextOptions fOptions; 147 const uint32_t fContextID; 148 sk_sp<const GrCaps> fCaps; 149 std::unique_ptr<GrTextBlobCache> fTextBlobCache; 150 std::unique_ptr<GrThreadSafeCache> fThreadSafeCache; 151 sk_sp<GrThreadSafePipelineBuilder> fPipelineBuilder; 152 std::atomic<bool> fAbandoned{false}; 153 }; 154 155 #else // !SK_SUPPORT_GPU 156 class SK_API GrContextThreadSafeProxy final : public SkNVRefCnt<GrContextThreadSafeProxy> {}; 157 #endif 158 159 #endif 160