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