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 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef skgpu_graphite_ContextOptions_DEFINED
#define skgpu_graphite_ContextOptions_DEFINED
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkSpan.h"
#include "include/private/base/SkAPI.h"
#include "include/private/base/SkMath.h"
#include <optional>
class SkData;
class SkExecutor;
class SkRuntimeEffect;
namespace skgpu { class ShaderErrorHandler; }
namespace skgpu::graphite {
struct ContextOptionsPriv;
struct SK_API ContextOptions {
ContextOptions() {}
/**
* Disables correctness workarounds that are enabled for particular GPUs, OSes, or drivers.
* This does not affect code path choices that are made for perfomance reasons nor does it
* override other ContextOption settings.
*/
bool fDisableDriverCorrectnessWorkarounds = false;
/**
* If present, use this object to report shader compilation failures. If not, report failures
* via SkDebugf and assert.
*/
skgpu::ShaderErrorHandler* fShaderErrorHandler = nullptr;
/**
* Specifies the number of samples Graphite should use when performing internal draws with MSAA
* (hardware capabilities permitting).
*
* If <= 1, Graphite will disable internal code paths that use multisampling.
*/
uint8_t fInternalMultisampleCount = 4;
/**
* If set, this specifies the max width/height of MSAA textures that Graphite should use for
* internal draws. Graphite might have to break the drawing region into multiple tiles to
* satisfy the size constraint.
* Note: this option will be ignored if the backend doesn't support it, or if a more optimal HW
* feature is available.
*/
std::optional<SkISize> fInternalMSAATileSize = std::nullopt;
/**
* If set, paths that are smaller than this size (in device space) will avoid MSAA techniques,
* even if MSAA is otherwise enabled via `fInternalMultisampleCount`. This should be smaller
* than `fGlyphsAsPathsFontSize` or large glyphs will not correctly avoid higher memory
* overhead.
*/
float fMinimumPathSizeForMSAA = 0;
/**
* Will the client make sure to only ever be executing one thread that uses the Context and all
* derived classes (e.g. Recorders, Recordings, etc.) at a time. If so we can possibly make some
* objects (e.g. VulkanMemoryAllocator) not thread safe to improve single thread performance.
*/
bool fClientWillExternallySynchronizeAllThreads = false;
/**
* The maximum size of cache textures used for Skia's Glyph cache.
*/
size_t fGlyphCacheTextureMaximumBytes = 2048 * 1024 * 4;
/**
* Below this threshold size in device space distance field fonts won't be used. Distance field
* fonts don't support hinting which is more important at smaller sizes.
*/
float fMinDistanceFieldFontSize = 18;
/**
* Above this threshold size in device space glyphs are drawn as individual paths.
*/
#if defined(SK_BUILD_FOR_ANDROID)
float fGlyphsAsPathsFontSize = 384;
#elif defined(SK_BUILD_FOR_MAC)
float fGlyphsAsPathsFontSize = 256;
#else
float fGlyphsAsPathsFontSize = 324;
#endif
/**
* The maximum size of textures used for Skia's PathAtlas caches.
*/
int fMaxPathAtlasTextureSize = 8192; // oversized, PathAtlas will likely be smaller
/**
* Can the glyph and path atlases use multiple textures. If allowed, each texture's size is
* bound by fGlyphCacheTextureMaximumBytes and fMaxPathAtlasTextureSize, respectively.
*/
bool fAllowMultipleAtlasTextures = true;
bool fSupportBilerpFromGlyphAtlas = false;
/**
* For the moment, if Recordings from the same Recorder are replayed in the order they are
* recorded, then Graphite can make certain assumptions that allow for better performance.
* Otherwise we have to flush some caches at the start of each Recording to ensure that they can
* be played back properly.
*
* This is the default ordering requirement for a Recorder. It can be overridden by
* setting the same field on the RecorderOptions passed to makeRecorder.
*
* Regardless of this value or a per-Recorder's setting, Recordings from separate Recorders can
* always be inserted in any order but it is the application's responsible to ensure that any
* implicit dependencies between the Recorders are respected (e.g. rendering to an SkSurface
* in one Recorder and sampling from that SkSurface's SkImage view on another Recorder).
*/
bool fRequireOrderedRecordings = false;
static constexpr size_t kDefaultContextBudget = 256 * (1 << 20);
/**
* What is the budget for GPU resources allocated and held by the Context.
*/
size_t fGpuBudgetInBytes = kDefaultContextBudget;
/**
* Whether labels will be set on backend resources.
*/
#if defined(SK_DEBUG)
bool fSetBackendLabels = true;
#else
bool fSetBackendLabels = false;
#endif
/**
* If Skia is creating a default VMA allocator for the Vulkan backend this value will be used
* for the preferredLargeHeapBlockSize. If the value is not set, then Skia will use an
* inernally defined default size.
*
* However, it is highly discouraged to have Skia make a default allocator (and support for
* doing so will be removed soon, b/321962001). Instead clients should create their own
* allocator to pass into Skia where they can fine tune this value themeselves.
*/
std::optional<uint64_t> fVulkanVMALargeHeapBlockSize;
/** Client-provided context that is passed to client-provided PipelineCallback. */
using PipelineCallbackContext = void*;
/** Client-provided callback that is called whenever Graphite encounters a new Pipeline. */
using PipelineCallback = void (*)(PipelineCallbackContext context, sk_sp<SkData> pipelineData);
/**
* These two members allow a client to register a callback that will be invoked
* whenever Graphite encounters a new Pipeline. The callback will be passed an
* sk_sp<SkData> that a client can take ownership of and serialize. The SkData
* contains all the information Graphite requires to recreate the Pipeline at
* a later date. The SkData is versioned however, so must be regenerated and
* re-serialized when it becomes out of date.
*/
PipelineCallbackContext fPipelineCallbackContext = nullptr;
PipelineCallback fPipelineCallback = nullptr;
/**
* The runtime effects provided here will be registered as user-defined *known* runtime
* effects and will be given a stable key. Such runtime effects can then be used in
* serialized pipeline keys (c.f. PrecompileContext::precompile).
*
* Graphite will take a ref on the provided runtime effects and they will persist for as long
* as the Context exists. Rather than recreating new SkRuntimeEffects using the same SkSL,
* clients should use the existing SkRuntimeEffects provided here.
*
* Warning: Registering runtime effects here does obligate users to clear out their caches
* of serialized pipeline keys if the provided runtime effects ever change in a meaningful way.
* This includes adding, removing or reordering the effects provided here.
*/
SkSpan<sk_sp<SkRuntimeEffect>> fUserDefinedKnownRuntimeEffects;
/**
* Executor to handle threaded work within Graphite. If this is nullptr, then all work will be
* done serially on the main thread. To have worker threads assist with various tasks, set this
* to a valid SkExecutor instance. Currently, used for Pipeline compilation, but may be used
* for other tasks. It is up to the client to ensure the SkExecutor remains valid throughout
* the lifetime of the Context.
*/
SkExecutor* fExecutor = nullptr;
/**
* An experimental flag in development. Behavior and performance is subject to change.
*
* Enables the use of startCapture and endCapture functions. Calling these APIs will capture all
* draw calls and surface creation from Recorders spawned from the Context.
*/
bool fEnableCapture = false;
/**
* Private options that are only meant for testing within Skia's tools.
*/
ContextOptionsPriv* fOptionsPriv = nullptr;
};
} // namespace skgpu::graphite
#endif // skgpu_graphite_ContextOptions
|