GrContext.h revision c49e8682ab0614e1b6816dadd00f65d770ab6999
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 /** 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 devProps the device 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 render target. 232 * @param target the render target 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 config or because no render target is currently set and NULL was passed for 245 * target. 246 */ 247 bool readRenderTargetPixels(GrRenderTarget* target, 248 int left, int top, int width, int height, 249 GrPixelConfig config, void* buffer, 250 size_t rowBytes = 0, 251 uint32_t pixelOpsFlags = 0); 252 253 /** 254 * Writes a rectangle of pixels to a surface. 255 * @param surface the surface to write to. 256 * @param left left edge of the rectangle to write (inclusive) 257 * @param top top edge of the rectangle to write (inclusive) 258 * @param width width of rectangle to write in pixels. 259 * @param height height of rectangle to write in pixels. 260 * @param config the pixel config of the source buffer 261 * @param buffer memory to read pixels from 262 * @param rowBytes number of bytes between consecutive rows. Zero 263 * means rows are tightly packed. 264 * @param pixelOpsFlags see PixelOpsFlags enum above. 265 * @return true if the write succeeded, false if not. The write can fail because of an 266 * unsupported combination of surface and src configs. 267 */ 268 bool writeSurfacePixels(GrSurface* surface, 269 int left, int top, int width, int height, 270 GrPixelConfig config, const void* buffer, 271 size_t rowBytes, 272 uint32_t pixelOpsFlags = 0); 273 274 /** 275 * Copies a rectangle of texels from src to dst. 276 * bounds. 277 * @param dst the surface to copy to. 278 * @param src the surface to copy from. 279 * @param srcRect the rectangle of the src that should be copied. 280 * @param dstPoint the translation applied when writing the srcRect's pixels to the dst. 281 * @param pixelOpsFlags see PixelOpsFlags enum above. (kUnpremul_PixelOpsFlag is not allowed). 282 */ 283 void copySurface(GrSurface* dst, 284 GrSurface* src, 285 const SkIRect& srcRect, 286 const SkIPoint& dstPoint, 287 uint32_t pixelOpsFlags = 0); 288 289 /** Helper that copies the whole surface but fails when the two surfaces are not identically 290 sized. */ 291 bool copySurface(GrSurface* dst, GrSurface* src) { 292 if (NULL == dst || NULL == src || dst->width() != src->width() || 293 dst->height() != src->height()) { 294 return false; 295 } 296 this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()), 297 SkIPoint::Make(0,0)); 298 return true; 299 } 300 301 /** 302 * After this returns any pending writes to the surface will have been issued to the backend 3D API. 303 */ 304 void flushSurfaceWrites(GrSurface* surface); 305 306 /** 307 * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve 308 * if necessary. 309 * 310 * It is not necessary to call this before reading the render target via Skia/GrContext. 311 * GrContext will detect when it must perform a resolve before reading pixels back from the 312 * surface or using it as a texture. 313 */ 314 void prepareSurfaceForExternalIO(GrSurface*); 315 316 /** 317 * An ID associated with this context, guaranteed to be unique. 318 */ 319 uint32_t uniqueID() { return fUniqueID; } 320 321 /////////////////////////////////////////////////////////////////////////// 322 // Functions intended for internal use only. 323 GrGpu* getGpu() { return fGpu; } 324 const GrGpu* getGpu() const { return fGpu; } 325 GrBatchFontCache* getBatchFontCache() { return fBatchFontCache; } 326 GrLayerCache* getLayerCache() { return fLayerCache.get(); } 327 GrTextBlobCache* getTextBlobCache() { return fTextBlobCache; } 328 bool abandoned() const { return fDrawingMgr.abandoned(); } 329 GrResourceProvider* resourceProvider() { return fResourceProvider; } 330 const GrResourceProvider* resourceProvider() const { return fResourceProvider; } 331 GrResourceCache* getResourceCache() { return fResourceCache; } 332 333 // Called by tests that draw directly to the context via GrDrawTarget 334 void getTestTarget(GrTestTarget*); 335 336 void addGpuTraceMarker(const GrGpuTraceMarker* marker); 337 void removeGpuTraceMarker(const GrGpuTraceMarker* marker); 338 339 GrPathRenderer* getPathRenderer( 340 const GrDrawTarget* target, 341 const GrPipelineBuilder*, 342 const SkMatrix& viewMatrix, 343 const SkPath& path, 344 const GrStrokeInfo& stroke, 345 bool allowSW, 346 GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, 347 GrPathRendererChain::StencilSupport* stencilSupport = NULL); 348 349 /** Prints cache stats to the string if GR_CACHE_STATS == 1. */ 350 void dumpCacheStats(SkString*) const; 351 void printCacheStats() const; 352 353 /** Prints GPU stats to the string if GR_GPU_STATS == 1. */ 354 void dumpGpuStats(SkString*) const; 355 void printGpuStats() const; 356 357private: 358 GrGpu* fGpu; 359 const GrCaps* fCaps; 360 GrResourceCache* fResourceCache; 361 // this union exists because the inheritance of GrTextureProvider->GrResourceProvider 362 // is in a private header. 363 union { 364 GrResourceProvider* fResourceProvider; 365 GrTextureProvider* fTextureProvider; 366 }; 367 368 GrBatchFontCache* fBatchFontCache; 369 SkAutoTDelete<GrLayerCache> fLayerCache; 370 SkAutoTDelete<GrTextBlobCache> fTextBlobCache; 371 372 GrPathRendererChain* fPathRendererChain; 373 GrSoftwarePathRenderer* fSoftwarePathRenderer; 374 375 // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. 376 bool fFlushToReduceCacheSize; 377 bool fDidTestPMConversions; 378 int fPMToUPMConversion; 379 int fUPMToPMConversion; 380 381 struct CleanUpData { 382 PFCleanUpFunc fFunc; 383 void* fInfo; 384 }; 385 386 SkTDArray<CleanUpData> fCleanUpData; 387 388 const uint32_t fUniqueID; 389 390 GrContext(); // init must be called after the constructor. 391 bool init(GrBackend, GrBackendContext, const GrContextOptions& options); 392 393 // Currently the DrawingMgr stores a separate GrDrawContext for each 394 // combination of text drawing options (pixel geometry x DFT use) 395 // and hands the appropriate one back given the user's request. 396 // All of the GrDrawContexts still land in the same GrDrawTarget! 397 // 398 // In the future this class will allocate a new GrDrawContext for 399 // each GrRenderTarget/GrDrawTarget and manage the DAG. 400 class DrawingMgr { 401 public: 402 DrawingMgr() : fDrawTarget(NULL) { 403 sk_bzero(fDrawContext, sizeof(fDrawContext)); 404 } 405 406 ~DrawingMgr(); 407 408 void init(GrContext* context); 409 410 void abandon(); 411 bool abandoned() const { return NULL == fDrawTarget; } 412 413 void purgeResources(); 414 void reset(); 415 void flush(); 416 417 // Callers should take a ref if they rely on the GrDrawContext sticking around. 418 // NULL will be returned if the context has been abandoned. 419 GrDrawContext* drawContext(const SkSurfaceProps* surfaceProps); 420 421 private: 422 void cleanup(); 423 424 friend class GrContext; // for access to fDrawTarget for testing 425 426 static const int kNumPixelGeometries = 5; // The different pixel geometries 427 static const int kNumDFTOptions = 2; // DFT or no DFT 428 429 GrContext* fContext; 430 GrDrawTarget* fDrawTarget; 431 432 GrDrawContext* fDrawContext[kNumPixelGeometries][kNumDFTOptions]; 433 }; 434 435 DrawingMgr fDrawingMgr; 436 437 void initMockContext(); 438 void initCommon(); 439 440 /** 441 * These functions create premul <-> unpremul effects if it is possible to generate a pair 442 * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they 443 * return NULL. 444 */ 445 const GrFragmentProcessor* createPMToUPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&); 446 const GrFragmentProcessor* createUPMToPMEffect(GrTexture*, bool swapRAndB, const SkMatrix&); 447 448 /** 449 * This callback allows the resource cache to callback into the GrContext 450 * when the cache is still over budget after a purge. 451 */ 452 static void OverBudgetCB(void* data); 453 454 /** 455 * A callback similar to the above for use by the TextBlobCache 456 * TODO move textblob draw calls below context so we can use the call above. 457 */ 458 static void TextBlobCacheOverBudgetCB(void* data); 459 460 typedef SkRefCnt INHERITED; 461}; 462 463#endif 464