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