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