1 /* 2 * Copyright 2010 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 GrContext_DEFINED 9 #define GrContext_DEFINED 10 11 #include "GrCaps.h" 12 #include "GrColor.h" 13 #include "SkMatrix.h" 14 #include "SkPathEffect.h" 15 #include "SkTypes.h" 16 #include "../private/GrAuditTrail.h" 17 #include "../private/GrSingleOwner.h" 18 19 class GrAtlasGlyphCache; 20 struct GrContextOptions; 21 class GrContextPriv; 22 class GrContextThreadSafeProxy; 23 class GrDrawingManager; 24 struct GrDrawOpAtlasConfig; 25 class GrRenderTargetContext; 26 class GrFragmentProcessor; 27 class GrGpu; 28 class GrIndexBuffer; 29 class GrOvalRenderer; 30 class GrPath; 31 class GrResourceEntry; 32 class GrResourceCache; 33 class GrResourceProvider; 34 class GrSamplerParams; 35 class GrSurfaceProxy; 36 class GrTextBlobCache; 37 class GrTextContext; 38 class GrTextureProxy; 39 class GrVertexBuffer; 40 class GrSwizzle; 41 class SkTraceMemoryDump; 42 43 class SkImage; 44 class SkSurfaceProps; 45 46 class SK_API GrContext : public SkRefCnt { 47 public: 48 /** 49 * Creates a GrContext for a backend context. 50 */ 51 static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options); 52 static GrContext* Create(GrBackend, GrBackendContext); 53 54 #ifdef SK_METAL 55 /** 56 * Makes a GrContext which uses Metal as the backend. The device parameter is an MTLDevice 57 * and queue is an MTLCommandQueue which should be used by the backend. These objects must 58 * have a ref on them which can be transferred to Ganesh which will release the ref when the 59 * GrContext is destroyed. 60 */ 61 static sk_sp<GrContext> MakeMetal(void* device, void* queue, const GrContextOptions& options); 62 #endif 63 64 virtual ~GrContext(); 65 66 sk_sp<GrContextThreadSafeProxy> threadSafeProxy(); 67 68 /** 69 * The GrContext normally assumes that no outsider is setting state 70 * within the underlying 3D API's context/device/whatever. This call informs 71 * the context that the state was modified and it should resend. Shouldn't 72 * be called frequently for good performance. 73 * The flag bits, state, is dpendent on which backend is used by the 74 * context, either GL or D3D (possible in future). 75 */ 76 void resetContext(uint32_t state = kAll_GrBackendState); 77 78 /** 79 * Callback function to allow classes to cleanup on GrContext destruction. 80 * The 'info' field is filled in with the 'info' passed to addCleanUp. 81 */ 82 typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); 83 84 /** 85 * Add a function to be called from within GrContext's destructor. 86 * This gives classes a chance to free resources held on a per context basis. 87 * The 'info' parameter will be stored and passed to the callback function. 88 */ addCleanUp(PFCleanUpFunc cleanUp,void * info)89 void addCleanUp(PFCleanUpFunc cleanUp, void* info) { 90 CleanUpData* entry = fCleanUpData.push(); 91 92 entry->fFunc = cleanUp; 93 entry->fInfo = info; 94 } 95 96 /** 97 * Abandons all GPU resources and assumes the underlying backend 3D API context is not longer 98 * usable. Call this if you have lost the associated GPU context, and thus internal texture, 99 * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the 100 * GrContext and any of its created resource objects will not make backend 3D API calls. Content 101 * rendered but not previously flushed may be lost. After this function is called all subsequent 102 * calls on the GrContext will fail or be no-ops. 103 * 104 * The typical use case for this function is that the underlying 3D context was lost and further 105 * API calls may crash. 106 */ 107 void abandonContext(); 108 109 /** 110 * This is similar to abandonContext() however the underlying 3D context is not yet lost and 111 * the GrContext will cleanup all allocated resources before returning. After returning it will 112 * assume that the underlying context may no longer be valid. 113 * 114 * The typical use case for this function is that the client is going to destroy the 3D context 115 * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed 116 * elsewhere by either the client or Skia objects). 117 */ 118 void releaseResourcesAndAbandonContext(); 119 120 /////////////////////////////////////////////////////////////////////////// 121 // Resource Cache 122 123 /** 124 * Return the current GPU resource cache limits. 125 * 126 * @param maxResources If non-null, returns maximum number of resources that 127 * can be held in the cache. 128 * @param maxResourceBytes If non-null, returns maximum number of bytes of 129 * video memory that can be held in the cache. 130 */ 131 void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const; 132 133 /** 134 * Gets the current GPU resource cache usage. 135 * 136 * @param resourceCount If non-null, returns the number of resources that are held in the 137 * cache. 138 * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held 139 * in the cache. 140 */ 141 void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const; 142 143 /** 144 * Gets the number of bytes in the cache consumed by purgeable (e.g. unlocked) resources. 145 */ 146 size_t getResourceCachePurgeableBytes() const; 147 148 /** 149 * Specify the GPU resource cache limits. If the current cache exceeds either 150 * of these, it will be purged (LRU) to keep the cache within these limits. 151 * 152 * @param maxResources The maximum number of resources that can be held in 153 * the cache. 154 * @param maxResourceBytes The maximum number of bytes of video memory 155 * that can be held in the cache. 156 */ 157 void setResourceCacheLimits(int maxResources, size_t maxResourceBytes); 158 159 /** 160 * Frees GPU created by the context. Can be called to reduce GPU memory 161 * pressure. 162 */ 163 void freeGpuResources(); 164 165 /** 166 * Purge all the unlocked resources from the cache. 167 * This entry point is mainly meant for timing texture uploads 168 * and is not defined in normal builds of Skia. 169 */ 170 void purgeAllUnlockedResources(); 171 172 /** 173 * Purge GPU resources that haven't been used in the past 'ms' milliseconds, regardless of 174 * whether the context is currently under budget. 175 */ 176 void purgeResourcesNotUsedInMs(std::chrono::milliseconds ms); 177 178 /** 179 * Purge unlocked resources from the cache until the the provided byte count has been reached 180 * or we have purged all unlocked resources. The default policy is to purge in LRU order, but 181 * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other 182 * resource types. 183 * 184 * @param maxBytesToPurge the desired number of bytes to be purged. 185 * @param preferScratchResources If true scratch resources will be purged prior to other 186 * resource types. 187 */ 188 void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources); 189 190 /** Access the context capabilities */ caps()191 const GrCaps* caps() const { return fCaps; } 192 193 /** 194 * Returns the recommended sample count for a render target when using this 195 * context. 196 * 197 * @param config the configuration of the render target. 198 * @param dpi the display density in dots per inch. 199 * 200 * @return sample count that should be perform well and have good enough 201 * rendering quality for the display. Alternatively returns 0 if 202 * MSAA is not supported or recommended to be used by default. 203 */ 204 int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; 205 206 /* 207 * Create a new render target context backed by a deferred-style 208 * GrRenderTargetProxy. We guarantee that "asTextureProxy" will succeed for 209 * renderTargetContexts created via this entry point. 210 */ 211 sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext( 212 SkBackingFit fit, 213 int width, int height, 214 GrPixelConfig config, 215 sk_sp<SkColorSpace> colorSpace, 216 int sampleCnt = 0, 217 GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin, 218 const SkSurfaceProps* surfaceProps = nullptr, 219 SkBudgeted = SkBudgeted::kYes); 220 /* 221 * This method will attempt to create a renderTargetContext that has, at least, the number of 222 * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be 223 * converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA). 224 * SRGB-ness will be preserved. 225 */ 226 sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContextWithFallback( 227 SkBackingFit fit, 228 int width, int height, 229 GrPixelConfig config, 230 sk_sp<SkColorSpace> colorSpace, 231 int sampleCnt = 0, 232 GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin, 233 const SkSurfaceProps* surfaceProps = nullptr, 234 SkBudgeted budgeted = SkBudgeted::kYes); 235 236 /////////////////////////////////////////////////////////////////////////// 237 // Misc. 238 239 /** 240 * Call to ensure all drawing to the context has been issued to the 241 * underlying 3D API. 242 */ 243 void flush(); 244 245 /** 246 * An ID associated with this context, guaranteed to be unique. 247 */ uniqueID()248 uint32_t uniqueID() { return fUniqueID; } 249 250 /////////////////////////////////////////////////////////////////////////// 251 // Functions intended for internal use only. getGpu()252 GrGpu* getGpu() { return fGpu; } getGpu()253 const GrGpu* getGpu() const { return fGpu; } getAtlasGlyphCache()254 GrAtlasGlyphCache* getAtlasGlyphCache() { return fAtlasGlyphCache; } getTextBlobCache()255 GrTextBlobCache* getTextBlobCache() { return fTextBlobCache.get(); } 256 bool abandoned() const; resourceProvider()257 GrResourceProvider* resourceProvider() { return fResourceProvider; } resourceProvider()258 const GrResourceProvider* resourceProvider() const { return fResourceProvider; } getResourceCache()259 GrResourceCache* getResourceCache() { return fResourceCache; } 260 261 /** Reset GPU stats */ 262 void resetGpuStats() const ; 263 264 /** Prints cache stats to the string if GR_CACHE_STATS == 1. */ 265 void dumpCacheStats(SkString*) const; 266 void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; 267 void printCacheStats() const; 268 269 /** Prints GPU stats to the string if GR_GPU_STATS == 1. */ 270 void dumpGpuStats(SkString*) const; 271 void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; 272 void printGpuStats() const; 273 274 /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge. 275 this is for testing only */ 276 void setTextBlobCacheLimit_ForTesting(size_t bytes); 277 278 /** Specify the sizes of the GrAtlasTextContext atlases. The configs pointer below should be 279 to an array of 3 entries */ 280 void setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs); 281 282 /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */ 283 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const; 284 285 /** Get pointer to atlas texture for given mask format. Note that this wraps an 286 actively mutating texture in an SkImage. This could yield unexpected results 287 if it gets cached or used more generally. */ 288 sk_sp<SkImage> getFontAtlasImage_ForTesting(GrMaskFormat format); 289 getAuditTrail()290 GrAuditTrail* getAuditTrail() { return &fAuditTrail; } 291 292 /** This is only useful for debug purposes */ 293 SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } ) 294 295 // Provides access to functions that aren't part of the public API. 296 GrContextPriv contextPriv(); 297 const GrContextPriv contextPriv() const; 298 299 private: 300 GrGpu* fGpu; 301 const GrCaps* fCaps; 302 GrResourceCache* fResourceCache; 303 GrResourceProvider* fResourceProvider; 304 305 sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy; 306 307 GrAtlasGlyphCache* fAtlasGlyphCache; 308 std::unique_ptr<GrTextBlobCache> fTextBlobCache; 309 310 bool fDisableGpuYUVConversion; 311 bool fDidTestPMConversions; 312 // true if the PM/UPM conversion succeeded; false otherwise 313 bool fPMUPMConversionsRoundTrip; 314 315 // In debug builds we guard against improper thread handling 316 // This guard is passed to the GrDrawingManager and, from there to all the 317 // GrRenderTargetContexts. It is also passed to the GrResourceProvider and SkGpuDevice. 318 mutable GrSingleOwner fSingleOwner; 319 320 struct CleanUpData { 321 PFCleanUpFunc fFunc; 322 void* fInfo; 323 }; 324 325 SkTDArray<CleanUpData> fCleanUpData; 326 327 const uint32_t fUniqueID; 328 329 std::unique_ptr<GrDrawingManager> fDrawingManager; 330 331 GrAuditTrail fAuditTrail; 332 333 GrBackend fBackend; 334 335 // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending 336 friend class GrContextPriv; 337 338 GrContext(); // init must be called after the constructor. 339 bool init(GrBackend, GrBackendContext, const GrContextOptions& options); 340 bool init(const GrContextOptions& options); 341 342 /** 343 * These functions create premul <-> unpremul effects. If the second argument is 'true', they 344 * use the specialized round-trip effects from GrConfigConversionEffect, otherwise they 345 * create effects that do naive multiply or divide. 346 */ 347 sk_sp<GrFragmentProcessor> createPMToUPMEffect(sk_sp<GrFragmentProcessor>, 348 bool useConfigConversionEffect); 349 sk_sp<GrFragmentProcessor> createUPMToPMEffect(sk_sp<GrFragmentProcessor>, 350 bool useConfigConversionEffect); 351 352 /** 353 * Returns true if createPMtoUPMEffect and createUPMToPMEffect will succeed for non-sRGB 8888 354 * configs. In other words, did we find a pair of round-trip preserving conversion effects? 355 */ 356 bool validPMUPMConversionExists(); 357 358 /** 359 * A callback similar to the above for use by the TextBlobCache 360 * TODO move textblob draw calls below context so we can use the call above. 361 */ 362 static void TextBlobCacheOverBudgetCB(void* data); 363 364 typedef SkRefCnt INHERITED; 365 }; 366 367 /** 368 * Can be used to perform actions related to the generating GrContext in a thread safe manner. The 369 * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. 370 */ 371 class GrContextThreadSafeProxy : public SkRefCnt { 372 private: GrContextThreadSafeProxy(sk_sp<const GrCaps> caps,uint32_t uniqueID)373 GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID) 374 : fCaps(std::move(caps)) 375 , fContextUniqueID(uniqueID) {} 376 377 sk_sp<const GrCaps> fCaps; 378 uint32_t fContextUniqueID; 379 380 friend class GrContext; 381 friend class SkImage; 382 383 typedef SkRefCnt INHERITED; 384 }; 385 386 #endif 387