GrContext.h revision 85d9667f59d4138438427bb2cdf67992d100e1a0
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 "GrClip.h" 13#include "GrColor.h" 14#include "GrPaint.h" 15#include "GrRenderTarget.h" 16#include "GrTextureProvider.h" 17#include "SkMatrix.h" 18#include "SkPathEffect.h" 19#include "SkTypes.h" 20#include "../private/GrAuditTrail.h" 21#include "../private/GrSingleOwner.h" 22#include "../private/SkMutex.h" 23 24struct GrBatchAtlasConfig; 25class GrBatchFontCache; 26struct GrContextOptions; 27class GrContextThreadSafeProxy; 28class GrDrawingManager; 29class GrDrawContext; 30class GrDrawTarget; 31class GrFragmentProcessor; 32class GrGpu; 33class GrIndexBuffer; 34class GrLayerCache; 35class GrOvalRenderer; 36class GrPath; 37class GrPipelineBuilder; 38class GrResourceEntry; 39class GrResourceCache; 40class GrResourceProvider; 41class GrTestTarget; 42class GrTextBlobCache; 43class GrTextContext; 44class GrTextureParams; 45class GrVertexBuffer; 46class GrStrokeInfo; 47class GrSwizzle; 48class SkTraceMemoryDump; 49 50class SK_API GrContext : public SkRefCnt { 51public: 52 /** 53 * Creates a GrContext for a backend context. 54 */ 55 static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options); 56 static GrContext* Create(GrBackend, GrBackendContext); 57 58 /** 59 * Only defined in test apps. 60 */ 61 static GrContext* CreateMockContext(); 62 63 virtual ~GrContext(); 64 65 GrContextThreadSafeProxy* threadSafeProxy(); 66 67 /** 68 * The GrContext normally assumes that no outsider is setting state 69 * within the underlying 3D API's context/device/whatever. This call informs 70 * the context that the state was modified and it should resend. Shouldn't 71 * be called frequently for good performance. 72 * The flag bits, state, is dpendent on which backend is used by the 73 * context, either GL or D3D (possible in future). 74 */ 75 void resetContext(uint32_t state = kAll_GrBackendState); 76 77 /** 78 * Callback function to allow classes to cleanup on GrContext destruction. 79 * The 'info' field is filled in with the 'info' passed to addCleanUp. 80 */ 81 typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); 82 83 /** 84 * Add a function to be called from within GrContext's destructor. 85 * This gives classes a chance to free resources held on a per context basis. 86 * The 'info' parameter will be stored and passed to the callback function. 87 */ 88 void addCleanUp(PFCleanUpFunc cleanUp, void* info) { 89 CleanUpData* entry = fCleanUpData.push(); 90 91 entry->fFunc = cleanUp; 92 entry->fInfo = info; 93 } 94 95 /** 96 * Abandons all GPU resources and assumes the underlying backend 3D API context is not longer 97 * usable. Call this if you have lost the associated GPU context, and thus internal texture, 98 * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the 99 * GrContext and any of its created resource objects will not make backend 3D API calls. Content 100 * rendered but not previously flushed may be lost. After this function is called all subsequent 101 * calls on the GrContext will fail or be no-ops. 102 * 103 * The typical use case for this function is that the underlying 3D context was lost and further 104 * API calls may crash. 105 */ 106 void abandonContext(); 107 108 /** 109 * This is similar to abandonContext() however the underlying 3D context is not yet lost and 110 * the GrContext will cleanup all allocated resources before returning. After returning it will 111 * assume that the underlying context may no longer be valid. 112 * 113 * The typical use case for this function is that the client is going to destroy the 3D context 114 * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed 115 * elsewhere by either the client or Skia objects). 116 */ 117 void releaseResourcesAndAbandonContext(); 118 119 /////////////////////////////////////////////////////////////////////////// 120 // Resource Cache 121 122 /** 123 * Return the current GPU resource cache limits. 124 * 125 * @param maxResources If non-null, returns maximum number of resources that 126 * can be held in the cache. 127 * @param maxResourceBytes If non-null, returns maximum number of bytes of 128 * video memory that can be held in the cache. 129 */ 130 void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const; 131 132 /** 133 * Gets the current GPU resource cache usage. 134 * 135 * @param resourceCount If non-null, returns the number of resources that are held in the 136 * cache. 137 * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held 138 * in the cache. 139 */ 140 void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const; 141 142 /** 143 * Specify the GPU resource cache limits. If the current cache exceeds either 144 * of these, it will be purged (LRU) to keep the cache within these limits. 145 * 146 * @param maxResources The maximum number of resources that can be held in 147 * the cache. 148 * @param maxResourceBytes The maximum number of bytes of video memory 149 * that can be held in the cache. 150 */ 151 void setResourceCacheLimits(int maxResources, size_t maxResourceBytes); 152 153 GrTextureProvider* textureProvider() { return fTextureProvider; } 154 const GrTextureProvider* textureProvider() const { return fTextureProvider; } 155 156 /** 157 * Frees GPU created by the context. Can be called to reduce GPU memory 158 * pressure. 159 */ 160 void freeGpuResources(); 161 162 /** 163 * Purge all the unlocked resources from the cache. 164 * This entry point is mainly meant for timing texture uploads 165 * and is not defined in normal builds of Skia. 166 */ 167 void purgeAllUnlockedResources(); 168 169 /** Access the context capabilities */ 170 const GrCaps* caps() const { return fCaps; } 171 172 /** 173 * Returns the recommended sample count for a render target when using this 174 * context. 175 * 176 * @param config the configuration of the render target. 177 * @param dpi the display density in dots per inch. 178 * 179 * @return sample count that should be perform well and have good enough 180 * rendering quality for the display. Alternatively returns 0 if 181 * MSAA is not supported or recommended to be used by default. 182 */ 183 int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; 184 185 /** 186 * Returns a helper object to orchestrate draws. 187 * Callers assume the creation ref of the drawContext 188 * NULL will be returned if the context has been abandoned. 189 * 190 * @param rt the render target receiving the draws 191 * @param surfaceProps the surface properties (mainly defines text drawing) 192 * 193 * @return a draw context 194 */ 195 sk_sp<GrDrawContext> drawContext(sk_sp<GrRenderTarget> rt, const SkSurfaceProps* = nullptr); 196 197 /** 198 * Create both a GrRenderTarget and a matching GrDrawContext to wrap it. 199 * The created GrRenderTarget will always be budgeted. 200 */ 201 sk_sp<GrDrawContext> newDrawContext(SkBackingFit fit, 202 int width, int height, 203 GrPixelConfig config, 204 int sampleCnt = 0, 205 GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin, 206 const SkSurfaceProps* surfaceProps = nullptr); 207 208 /////////////////////////////////////////////////////////////////////////// 209 // Misc. 210 211 /** 212 * Flags that affect flush() behavior. 213 */ 214 enum FlushBits { 215 /** 216 * A client may reach a point where it has partially rendered a frame 217 * through a GrContext that it knows the user will never see. This flag 218 * causes the flush to skip submission of deferred content to the 3D API 219 * during the flush. 220 */ 221 kDiscard_FlushBit = 0x2, 222 }; 223 224 /** 225 * Call to ensure all drawing to the context has been issued to the 226 * underlying 3D API. 227 * @param flagsBitfield flags that control the flushing behavior. See 228 * FlushBits. 229 */ 230 void flush(int flagsBitfield = 0); 231 232 void flushIfNecessary() { 233 if (fFlushToReduceCacheSize || this->caps()->immediateFlush()) { 234 this->flush(); 235 } 236 } 237 238 /** 239 * These flags can be used with the read/write pixels functions below. 240 */ 241 enum PixelOpsFlags { 242 /** The GrContext will not be flushed before the surface read or write. This means that 243 the read or write may occur before previous draws have executed. */ 244 kDontFlush_PixelOpsFlag = 0x1, 245 /** Any surface writes should be flushed to the backend 3D API after the surface operation 246 is complete */ 247 kFlushWrites_PixelOp = 0x2, 248 /** The src for write or dst read is unpremultiplied. This is only respected if both the 249 config src and dst configs are an RGBA/BGRA 8888 format. */ 250 kUnpremul_PixelOpsFlag = 0x4, 251 }; 252 253 /** 254 * Reads a rectangle of pixels from a surface. 255 * @param surface the surface to read from. 256 * @param left left edge of the rectangle to read (inclusive) 257 * @param top top edge of the rectangle to read (inclusive) 258 * @param width width of rectangle to read in pixels. 259 * @param height height of rectangle to read in pixels. 260 * @param config the pixel config of the destination buffer 261 * @param buffer memory to read the rectangle into. 262 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly 263 * packed. 264 * @param pixelOpsFlags see PixelOpsFlags enum above. 265 * 266 * @return true if the read succeeded, false if not. The read can fail because of an unsupported 267 * pixel configs 268 */ 269 bool readSurfacePixels(GrSurface* surface, 270 int left, int top, int width, int height, 271 GrPixelConfig config, void* buffer, 272 size_t rowBytes = 0, 273 uint32_t pixelOpsFlags = 0); 274 275 /** 276 * Writes a rectangle of pixels to a surface. 277 * @param surface the surface to write to. 278 * @param left left edge of the rectangle to write (inclusive) 279 * @param top top edge of the rectangle to write (inclusive) 280 * @param width width of rectangle to write in pixels. 281 * @param height height of rectangle to write in pixels. 282 * @param config the pixel config of the source buffer 283 * @param buffer memory to read pixels from 284 * @param rowBytes number of bytes between consecutive rows. Zero 285 * means rows are tightly packed. 286 * @param pixelOpsFlags see PixelOpsFlags enum above. 287 * @return true if the write succeeded, false if not. The write can fail because of an 288 * unsupported combination of surface and src configs. 289 */ 290 bool writeSurfacePixels(GrSurface* surface, 291 int left, int top, int width, int height, 292 GrPixelConfig config, const void* buffer, 293 size_t rowBytes, 294 uint32_t pixelOpsFlags = 0); 295 296 /** 297 * Copies contents of src to dst, while applying a gamma curve. Fails if the two surfaces 298 * are not identically sized. 299 * @param dst the surface to copy to. 300 * @param src the texture to copy from. 301 * @param gamma the gamma value to apply. 302 */ 303 bool applyGamma(GrRenderTarget* dst, GrTexture* src, SkScalar gamma); 304 305 /** 306 * Copies a rectangle of texels from src to dst. 307 * @param dst the surface to copy to. 308 * @param src the surface to copy from. 309 * @param srcRect the rectangle of the src that should be copied. 310 * @param dstPoint the translation applied when writing the srcRect's pixels to the dst. 311 */ 312 bool copySurface(GrSurface* dst, 313 GrSurface* src, 314 const SkIRect& srcRect, 315 const SkIPoint& dstPoint); 316 317 /** Helper that copies the whole surface but fails when the two surfaces are not identically 318 sized. */ 319 bool copySurface(GrSurface* dst, GrSurface* src) { 320 return this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()), 321 SkIPoint::Make(0,0)); 322 } 323 324 /** 325 * After this returns any pending writes to the surface will have been issued to the backend 3D API. 326 */ 327 void flushSurfaceWrites(GrSurface* surface); 328 329 /** 330 * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve 331 * if necessary. 332 * 333 * It is not necessary to call this before reading the render target via Skia/GrContext. 334 * GrContext will detect when it must perform a resolve before reading pixels back from the 335 * surface or using it as a texture. 336 */ 337 void prepareSurfaceForExternalIO(GrSurface*); 338 339 /** 340 * An ID associated with this context, guaranteed to be unique. 341 */ 342 uint32_t uniqueID() { return fUniqueID; } 343 344 /////////////////////////////////////////////////////////////////////////// 345 // Functions intended for internal use only. 346 GrGpu* getGpu() { return fGpu; } 347 const GrGpu* getGpu() const { return fGpu; } 348 GrBatchFontCache* getBatchFontCache() { return fBatchFontCache; } 349 GrLayerCache* getLayerCache() { return fLayerCache.get(); } 350 GrTextBlobCache* getTextBlobCache() { return fTextBlobCache; } 351 bool abandoned() const; 352 GrResourceProvider* resourceProvider() { return fResourceProvider; } 353 const GrResourceProvider* resourceProvider() const { return fResourceProvider; } 354 GrResourceCache* getResourceCache() { return fResourceCache; } 355 356 // Called by tests that draw directly to the context via GrDrawTarget 357 void getTestTarget(GrTestTarget*, GrRenderTarget* rt); 358 359 /** Reset GPU stats */ 360 void resetGpuStats() const ; 361 362 /** Prints cache stats to the string if GR_CACHE_STATS == 1. */ 363 void dumpCacheStats(SkString*) const; 364 void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; 365 void printCacheStats() const; 366 367 /** Prints GPU stats to the string if GR_GPU_STATS == 1. */ 368 void dumpGpuStats(SkString*) const; 369 void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; 370 void printGpuStats() const; 371 372 /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge. 373 this is for testing only */ 374 void setTextBlobCacheLimit_ForTesting(size_t bytes); 375 376 /** Specify the sizes of the GrAtlasTextContext atlases. The configs pointer below should be 377 to an array of 3 entries */ 378 void setTextContextAtlasSizes_ForTesting(const GrBatchAtlasConfig* configs); 379 380 /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */ 381 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const; 382 383 /** Get pointer to atlas texture for given mask format */ 384 GrTexture* getFontAtlasTexture(GrMaskFormat format); 385 386 GrAuditTrail* getAuditTrail() { return &fAuditTrail; } 387 388 /** This is only useful for debug purposes */ 389 SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } ) 390 391private: 392 GrGpu* fGpu; 393 const GrCaps* fCaps; 394 GrResourceCache* fResourceCache; 395 // this union exists because the inheritance of GrTextureProvider->GrResourceProvider 396 // is in a private header. 397 union { 398 GrResourceProvider* fResourceProvider; 399 GrTextureProvider* fTextureProvider; 400 }; 401 402 SkAutoTUnref<GrContextThreadSafeProxy> fThreadSafeProxy; 403 404 GrBatchFontCache* fBatchFontCache; 405 SkAutoTDelete<GrLayerCache> fLayerCache; 406 SkAutoTDelete<GrTextBlobCache> fTextBlobCache; 407 408 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. 409 bool fFlushToReduceCacheSize; 410 bool fDidTestPMConversions; 411 int fPMToUPMConversion; 412 int fUPMToPMConversion; 413 // The sw backend may call GrContext::readSurfacePixels on multiple threads 414 // We may transfer the responsibilty for using a mutex to the sw backend 415 // when there are fewer code paths that lead to a readSurfacePixels call 416 // from the sw backend. readSurfacePixels is reentrant in one case - when performing 417 // the PM conversions test. To handle this we do the PM conversions test outside 418 // of fReadPixelsMutex and use a separate mutex to guard it. When it re-enters 419 // readSurfacePixels it will grab fReadPixelsMutex and release it before the outer 420 // readSurfacePixels proceeds to grab it. 421 // TODO: Stop pretending to make GrContext thread-safe for sw rasterization and provide 422 // a mechanism to make a SkPicture safe for multithreaded sw rasterization. 423 SkMutex fReadPixelsMutex; 424 SkMutex fTestPMConversionsMutex; 425 426 // In debug builds we guard against improper thread handling 427 // This guard is passed to the GrDrawingManager and, from there to all the 428 // GrDrawContexts. It is also passed to the GrTextureProvider and SkGpuDevice. 429 mutable GrSingleOwner fSingleOwner; 430 431 struct CleanUpData { 432 PFCleanUpFunc fFunc; 433 void* fInfo; 434 }; 435 436 SkTDArray<CleanUpData> fCleanUpData; 437 438 const uint32_t fUniqueID; 439 440 SkAutoTDelete<GrDrawingManager> fDrawingManager; 441 442 GrAuditTrail fAuditTrail; 443 444 // TODO: have the CMM use drawContexts and rm this friending 445 friend class GrClipMaskManager; // the CMM is friended just so it can call 'drawingManager' 446 friend class GrDrawingManager; // for access to drawingManager for ProgramUnitTest 447 GrDrawingManager* drawingManager() { return fDrawingManager; } 448 449 GrContext(); // init must be called after the constructor. 450 bool init(GrBackend, GrBackendContext, const GrContextOptions& options); 451 452 void initMockContext(); 453 void initCommon(const GrContextOptions&); 454 455 /** 456 * These functions create premul <-> unpremul effects if it is possible to generate a pair 457 * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they 458 * return NULL. They also can perform a swizzle as part of the draw. 459 */ 460 const GrFragmentProcessor* createPMToUPMEffect(GrTexture*, const GrSwizzle&, 461 const SkMatrix&) const; 462 const GrFragmentProcessor* createUPMToPMEffect(GrTexture*, const GrSwizzle&, 463 const SkMatrix&) const; 464 /** Called before either of the above two functions to determine the appropriate fragment 465 processors for conversions. This must be called by readSurfacePixels before a mutex is 466 taken, since testingvPM conversions itself will call readSurfacePixels */ 467 void testPMConversionsIfNecessary(uint32_t flags); 468 /** Returns true if we've already determined that createPMtoUPMEffect and createUPMToPMEffect 469 will fail. In such cases fall back to SW conversion. */ 470 bool didFailPMUPMConversionTest() const; 471 472 /** 473 * This callback allows the resource cache to callback into the GrContext 474 * when the cache is still over budget after a purge. 475 */ 476 static void OverBudgetCB(void* data); 477 478 /** 479 * A callback similar to the above for use by the TextBlobCache 480 * TODO move textblob draw calls below context so we can use the call above. 481 */ 482 static void TextBlobCacheOverBudgetCB(void* data); 483 484 typedef SkRefCnt INHERITED; 485}; 486 487/** 488 * Can be used to perform actions related to the generating GrContext in a thread safe manner. The 489 * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. 490 */ 491class GrContextThreadSafeProxy : public SkRefCnt { 492private: 493 GrContextThreadSafeProxy(const GrCaps* caps, uint32_t uniqueID) 494 : fCaps(SkRef(caps)) 495 , fContextUniqueID(uniqueID) {} 496 497 SkAutoTUnref<const GrCaps> fCaps; 498 uint32_t fContextUniqueID; 499 500 friend class GrContext; 501 friend class SkImage; 502 503 typedef SkRefCnt INHERITED; 504}; 505 506#endif 507