GrContext.h revision da04e0e80a0113e1d838f7406cd8a8d545b8c02b
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 "GrClip.h" 12#include "GrColor.h" 13#include "GrPaint.h" 14#include "GrPathRendererChain.h" 15#include "GrRenderTarget.h" 16#include "GrTextureProvider.h" 17#include "SkMatrix.h" 18#include "SkPathEffect.h" 19#include "SkTypes.h" 20 21struct GrBatchAtlasConfig; 22class GrBatchFontCache; 23class GrCaps; 24struct GrContextOptions; 25class GrDrawContext; 26class GrDrawTarget; 27class GrFragmentProcessor; 28class GrGpu; 29class GrGpuTraceMarker; 30class GrIndexBuffer; 31class GrLayerCache; 32class GrOvalRenderer; 33class GrPath; 34class GrPathRenderer; 35class GrPipelineBuilder; 36class GrResourceEntry; 37class GrResourceCache; 38class GrResourceProvider; 39class GrTestTarget; 40class GrTextBlobCache; 41class GrTextContext; 42class GrTextureParams; 43class GrVertexBuffer; 44class GrStrokeInfo; 45class GrSoftwarePathRenderer; 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 /** 63 * The GrContext normally assumes that no outsider is setting state 64 * within the underlying 3D API's context/device/whatever. This call informs 65 * the context that the state was modified and it should resend. Shouldn't 66 * be called frequently for good performance. 67 * The flag bits, state, is dpendent on which backend is used by the 68 * context, either GL or D3D (possible in future). 69 */ 70 void resetContext(uint32_t state = kAll_GrBackendState); 71 72 /** 73 * Callback function to allow classes to cleanup on GrContext destruction. 74 * The 'info' field is filled in with the 'info' passed to addCleanUp. 75 */ 76 typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); 77 78 /** 79 * Add a function to be called from within GrContext's destructor. 80 * This gives classes a chance to free resources held on a per context basis. 81 * The 'info' parameter will be stored and passed to the callback function. 82 */ 83 void addCleanUp(PFCleanUpFunc cleanUp, void* info) { 84 CleanUpData* entry = fCleanUpData.push(); 85 86 entry->fFunc = cleanUp; 87 entry->fInfo = info; 88 } 89 90 /** 91 * Abandons all GPU resources and assumes the underlying backend 3D API 92 * context is not longer usable. Call this if you have lost the associated 93 * GPU context, and thus internal texture, buffer, etc. references/IDs are 94 * now invalid. Should be called even when GrContext is no longer going to 95 * be used for two reasons: 96 * 1) ~GrContext will not try to free the objects in the 3D API. 97 * 2) Any GrGpuResources created by this GrContext that outlive 98 * will be marked as invalid (GrGpuResource::wasDestroyed()) and 99 * when they're destroyed no 3D API calls will be made. 100 * Content drawn since the last GrContext::flush() may be lost. After this 101 * function is called the only valid action on the GrContext or 102 * GrGpuResources it created is to destroy them. 103 */ 104 void abandonContext(); 105 106 /////////////////////////////////////////////////////////////////////////// 107 // Resource Cache 108 109 /** 110 * Return the current GPU resource cache limits. 111 * 112 * @param maxResources If non-null, returns maximum number of resources that 113 * can be held in the cache. 114 * @param maxResourceBytes If non-null, returns maximum number of bytes of 115 * video memory that can be held in the cache. 116 */ 117 void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const; 118 119 /** 120 * Gets the current GPU resource cache usage. 121 * 122 * @param resourceCount If non-null, returns the number of resources that are held in the 123 * cache. 124 * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held 125 * in the cache. 126 */ 127 void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const; 128 129 /** 130 * Specify the GPU resource cache limits. If the current cache exceeds either 131 * of these, it will be purged (LRU) to keep the cache within these limits. 132 * 133 * @param maxResources The maximum number of resources that can be held in 134 * the cache. 135 * @param maxResourceBytes The maximum number of bytes of video memory 136 * that can be held in the cache. 137 */ 138 void setResourceCacheLimits(int maxResources, size_t maxResourceBytes); 139 140 GrTextureProvider* textureProvider() { return fTextureProvider; } 141 const GrTextureProvider* textureProvider() const { return fTextureProvider; } 142 143 /** 144 * Frees GPU created by the context. Can be called to reduce GPU memory 145 * pressure. 146 */ 147 void freeGpuResources(); 148 149 /** 150 * Purge all the unlocked resources from the cache. 151 * This entry point is mainly meant for timing texture uploads 152 * and is not defined in normal builds of Skia. 153 */ 154 void purgeAllUnlockedResources(); 155 156 /** Access the context capabilities */ 157 const GrCaps* caps() const { return fCaps; } 158 159 /** 160 * Returns the recommended sample count for a render target when using this 161 * context. 162 * 163 * @param config the configuration of the render target. 164 * @param dpi the display density in dots per inch. 165 * 166 * @return sample count that should be perform well and have good enough 167 * rendering quality for the display. Alternatively returns 0 if 168 * MSAA is not supported or recommended to be used by default. 169 */ 170 int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; 171 172 /** 173 * Returns a helper object to orchestrate draws. 174 * Callers should take a ref if they rely on the GrDrawContext sticking around. 175 * NULL will be returned if the context has been abandoned. 176 * 177 * @param surfaceProps the surface properties (mainly defines text drawing) 178 * 179 * @return a draw context 180 */ 181 GrDrawContext* drawContext(const SkSurfaceProps* surfaceProps = NULL) { 182 return fDrawingMgr.drawContext(surfaceProps); 183 } 184 185 /////////////////////////////////////////////////////////////////////////// 186 // Misc. 187 188 /** 189 * Flags that affect flush() behavior. 190 */ 191 enum FlushBits { 192 /** 193 * A client may reach a point where it has partially rendered a frame 194 * through a GrContext that it knows the user will never see. This flag 195 * causes the flush to skip submission of deferred content to the 3D API 196 * during the flush. 197 */ 198 kDiscard_FlushBit = 0x2, 199 }; 200 201 /** 202 * Call to ensure all drawing to the context has been issued to the 203 * underlying 3D API. 204 * @param flagsBitfield flags that control the flushing behavior. See 205 * FlushBits. 206 */ 207 void flush(int flagsBitfield = 0); 208 209 void flushIfNecessary() { 210 if (fFlushToReduceCacheSize) { 211 this->flush(); 212 } 213 } 214 215 /** 216 * These flags can be used with the read/write pixels functions below. 217 */ 218 enum PixelOpsFlags { 219 /** The GrContext will not be flushed before the surface read or write. This means that 220 the read or write may occur before previous draws have executed. */ 221 kDontFlush_PixelOpsFlag = 0x1, 222 /** Any surface writes should be flushed to the backend 3D API after the surface operation 223 is complete */ 224 kFlushWrites_PixelOp = 0x2, 225 /** The src for write or dst read is unpremultiplied. This is only respected if both the 226 config src and dst configs are an RGBA/BGRA 8888 format. */ 227 kUnpremul_PixelOpsFlag = 0x4, 228 }; 229 230 /** 231 * Reads a rectangle of pixels from a surface. 232 * @param surface the surface to read from. 233 * @param left left edge of the rectangle to read (inclusive) 234 * @param top top edge of the rectangle to read (inclusive) 235 * @param width width of rectangle to read in pixels. 236 * @param height height of rectangle to read in pixels. 237 * @param config the pixel config of the destination buffer 238 * @param buffer memory to read the rectangle into. 239 * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly 240 * packed. 241 * @param pixelOpsFlags see PixelOpsFlags enum above. 242 * 243 * @return true if the read succeeded, false if not. The read can fail because of an unsupported 244 * pixel configs 245 */ 246 bool readSurfacePixels(GrSurface* surface, 247 int left, int top, int width, int height, 248 GrPixelConfig config, void* buffer, 249 size_t rowBytes = 0, 250 uint32_t pixelOpsFlags = 0); 251 252 /** 253 * Writes a rectangle of pixels to a surface. 254 * @param surface the surface to write to. 255 * @param left left edge of the rectangle to write (inclusive) 256 * @param top top edge of the rectangle to write (inclusive) 257 * @param width width of rectangle to write in pixels. 258 * @param height height of rectangle to write in pixels. 259 * @param config the pixel config of the source buffer 260 * @param buffer memory to read pixels from 261 * @param rowBytes number of bytes between consecutive rows. Zero 262 * means rows are tightly packed. 263 * @param pixelOpsFlags see PixelOpsFlags enum above. 264 * @return true if the write succeeded, false if not. The write can fail because of an 265 * unsupported combination of surface and src configs. 266 */ 267 bool writeSurfacePixels(GrSurface* surface, 268 int left, int top, int width, int height, 269 GrPixelConfig config, const void* buffer, 270 size_t rowBytes, 271 uint32_t pixelOpsFlags = 0); 272 273 /** 274 * Copies a rectangle of texels from src to dst. 275 * bounds. 276 * @param dst the surface to copy to. 277 * @param src the surface to copy from. 278 * @param srcRect the rectangle of the src that should be copied. 279 * @param dstPoint the translation applied when writing the srcRect's pixels to the dst. 280 * @param pixelOpsFlags see PixelOpsFlags enum above. (kUnpremul_PixelOpsFlag is not allowed). 281 */ 282 void copySurface(GrSurface* dst, 283 GrSurface* src, 284 const SkIRect& srcRect, 285 const SkIPoint& dstPoint, 286 uint32_t pixelOpsFlags = 0); 287 288 /** Helper that copies the whole surface but fails when the two surfaces are not identically 289 sized. */ 290 bool copySurface(GrSurface* dst, GrSurface* src) { 291 if (NULL == dst || NULL == src || dst->width() != src->width() || 292 dst->height() != src->height()) { 293 return false; 294 } 295 this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()), 296 SkIPoint::Make(0,0)); 297 return true; 298 } 299 300 /** 301 * After this returns any pending writes to the surface will have been issued to the backend 3D API. 302 */ 303 void flushSurfaceWrites(GrSurface* surface); 304 305 /** 306 * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve 307 * if necessary. 308 * 309 * It is not necessary to call this before reading the render target via Skia/GrContext. 310 * GrContext will detect when it must perform a resolve before reading pixels back from the 311 * surface or using it as a texture. 312 */ 313 void prepareSurfaceForExternalIO(GrSurface*); 314 315 /** 316 * An ID associated with this context, guaranteed to be unique. 317 */ 318 uint32_t uniqueID() { return fUniqueID; } 319 320 /////////////////////////////////////////////////////////////////////////// 321 // Functions intended for internal use only. 322 GrGpu* getGpu() { return fGpu; } 323 const GrGpu* getGpu() const { return fGpu; } 324 GrBatchFontCache* getBatchFontCache() { return fBatchFontCache; } 325 GrLayerCache* getLayerCache() { return fLayerCache.get(); } 326 GrTextBlobCache* getTextBlobCache() { return fTextBlobCache; } 327 bool abandoned() const { return fDrawingMgr.abandoned(); } 328 GrResourceProvider* resourceProvider() { return fResourceProvider; } 329 const GrResourceProvider* resourceProvider() const { return fResourceProvider; } 330 GrResourceCache* getResourceCache() { return fResourceCache; } 331 332 // Called by tests that draw directly to the context via GrDrawTarget 333 void getTestTarget(GrTestTarget*); 334 335 void addGpuTraceMarker(const GrGpuTraceMarker* marker); 336 void removeGpuTraceMarker(const GrGpuTraceMarker* marker); 337 338 GrPathRenderer* getPathRenderer( 339 const GrDrawTarget* target, 340 const GrPipelineBuilder*, 341 const SkMatrix& viewMatrix, 342 const SkPath& path, 343 const GrStrokeInfo& stroke, 344 bool allowSW, 345 GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, 346 GrPathRendererChain::StencilSupport* stencilSupport = NULL); 347 348 /** Prints cache stats to the string if GR_CACHE_STATS == 1. */ 349 void dumpCacheStats(SkString*) const; 350 void printCacheStats() const; 351 352 /** Prints GPU stats to the string if GR_GPU_STATS == 1. */ 353 void dumpGpuStats(SkString*) const; 354 void printGpuStats() const; 355 356 /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge. 357 this is for testing only */ 358 void setTextBlobCacheLimit_ForTesting(size_t bytes); 359 360 /** Specify the sizes of the GrAtlasTextContext atlases. The configs pointer below should be 361 to an array of 3 entries */ 362 void setTextContextAtlasSizes_ForTesting(const GrBatchAtlasConfig* configs); 363 364private: 365 GrGpu* fGpu; 366 const GrCaps* fCaps; 367 GrResourceCache* fResourceCache; 368 // this union exists because the inheritance of GrTextureProvider->GrResourceProvider 369 // is in a private header. 370 union { 371 GrResourceProvider* fResourceProvider; 372 GrTextureProvider* fTextureProvider; 373 }; 374 375 GrBatchFontCache* fBatchFontCache; 376 SkAutoTDelete<GrLayerCache> fLayerCache; 377 SkAutoTDelete<GrTextBlobCache> fTextBlobCache; 378 379 GrPathRendererChain* fPathRendererChain; 380 GrSoftwarePathRenderer* fSoftwarePathRenderer; 381 382 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. 383 bool fFlushToReduceCacheSize; 384 bool fDidTestPMConversions; 385 int fPMToUPMConversion; 386 int fUPMToPMConversion; 387 388 struct CleanUpData { 389 PFCleanUpFunc fFunc; 390 void* fInfo; 391 }; 392 393 SkTDArray<CleanUpData> fCleanUpData; 394 395 const uint32_t fUniqueID; 396 397 GrContext(); // init must be called after the constructor. 398 bool init(GrBackend, GrBackendContext, const GrContextOptions& options); 399 400 // Currently the DrawingMgr stores a separate GrDrawContext for each 401 // combination of text drawing options (pixel geometry x DFT use) 402 // and hands the appropriate one back given the user's request. 403 // All of the GrDrawContexts still land in the same GrDrawTarget! 404 // 405 // In the future this class will allocate a new GrDrawContext for 406 // each GrRenderTarget/GrDrawTarget and manage the DAG. 407 class DrawingMgr { 408 public: 409 DrawingMgr() : fDrawTarget(NULL) { 410 sk_bzero(fDrawContext, sizeof(fDrawContext)); 411 } 412 413 ~DrawingMgr(); 414 415 void init(GrContext* context); 416 417 void abandon(); 418 bool abandoned() const { return NULL == fDrawTarget; } 419 420 void purgeResources(); 421 void reset(); 422 void flush(); 423 424 // Callers should take a ref if they rely on the GrDrawContext sticking around. 425 // NULL will be returned if the context has been abandoned. 426 GrDrawContext* drawContext(const SkSurfaceProps* surfaceProps); 427 428 private: 429 void cleanup(); 430 431 friend class GrContext; // for access to fDrawTarget for testing 432 433 static const int kNumPixelGeometries = 5; // The different pixel geometries 434 static const int kNumDFTOptions = 2; // DFT or no DFT 435 436 GrContext* fContext; 437 GrDrawTarget* fDrawTarget; 438 439 GrDrawContext* fDrawContext[kNumPixelGeometries][kNumDFTOptions]; 440 }; 441 442 DrawingMgr fDrawingMgr; 443 444 void initMockContext(); 445 void initCommon(); 446 447 /** 448 * These functions create premul <-> unpremul effects if it is possible to generate a pair 449 * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they 450 * return NULL. 451 */ 452 const GrFragmentProcessor* createPMToUPMEffect(GrProcessorDataManager*, GrTexture*, 453 bool swapRAndB, const SkMatrix&); 454 const GrFragmentProcessor* createUPMToPMEffect(GrProcessorDataManager*, GrTexture*, 455 bool swapRAndB, const SkMatrix&); 456 /** Returns true if we've already determined that createPMtoUPMEffect and createUPMToPMEffect 457 will fail. In such cases fall back to SW conversion. */ 458 bool didFailPMUPMConversionTest() const; 459 460 /** 461 * This callback allows the resource cache to callback into the GrContext 462 * when the cache is still over budget after a purge. 463 */ 464 static void OverBudgetCB(void* data); 465 466 /** 467 * A callback similar to the above for use by the TextBlobCache 468 * TODO move textblob draw calls below context so we can use the call above. 469 */ 470 static void TextBlobCacheOverBudgetCB(void* data); 471 472 typedef SkRefCnt INHERITED; 473}; 474 475#endif 476