diff options
Diffstat (limited to 'gfx/skia/skia/include/gpu/GrContext.h')
-rw-r--r-- | gfx/skia/skia/include/gpu/GrContext.h | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/gfx/skia/skia/include/gpu/GrContext.h b/gfx/skia/skia/include/gpu/GrContext.h new file mode 100644 index 000000000..996b77f2d --- /dev/null +++ b/gfx/skia/skia/include/gpu/GrContext.h @@ -0,0 +1,479 @@ +/* + * Copyright 2010 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrContext_DEFINED +#define GrContext_DEFINED + +#include "GrCaps.h" +#include "GrClip.h" +#include "GrColor.h" +#include "GrPaint.h" +#include "GrRenderTarget.h" +#include "GrTextureProvider.h" +#include "SkMatrix.h" +#include "SkPathEffect.h" +#include "SkTypes.h" +#include "../private/GrAuditTrail.h" +#include "../private/GrSingleOwner.h" +#include "../private/SkMutex.h" + +struct GrBatchAtlasConfig; +class GrBatchFontCache; +struct GrContextOptions; +class GrContextPriv; +class GrContextThreadSafeProxy; +class GrDrawingManager; +class GrDrawContext; +class GrFragmentProcessor; +class GrGpu; +class GrIndexBuffer; +class GrOvalRenderer; +class GrPath; +class GrPipelineBuilder; +class GrResourceEntry; +class GrResourceCache; +class GrResourceProvider; +class GrTestTarget; +class GrTextBlobCache; +class GrTextContext; +class GrTextureParams; +class GrVertexBuffer; +class GrSwizzle; +class SkTraceMemoryDump; + +class SK_API GrContext : public SkRefCnt { +public: + /** + * Creates a GrContext for a backend context. + */ + static GrContext* Create(GrBackend, GrBackendContext, const GrContextOptions& options); + static GrContext* Create(GrBackend, GrBackendContext); + + /** + * Only defined in test apps. + */ + static GrContext* CreateMockContext(); + + virtual ~GrContext(); + + GrContextThreadSafeProxy* threadSafeProxy(); + + /** + * The GrContext normally assumes that no outsider is setting state + * within the underlying 3D API's context/device/whatever. This call informs + * the context that the state was modified and it should resend. Shouldn't + * be called frequently for good performance. + * The flag bits, state, is dpendent on which backend is used by the + * context, either GL or D3D (possible in future). + */ + void resetContext(uint32_t state = kAll_GrBackendState); + + /** + * Callback function to allow classes to cleanup on GrContext destruction. + * The 'info' field is filled in with the 'info' passed to addCleanUp. + */ + typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); + + /** + * Add a function to be called from within GrContext's destructor. + * This gives classes a chance to free resources held on a per context basis. + * The 'info' parameter will be stored and passed to the callback function. + */ + void addCleanUp(PFCleanUpFunc cleanUp, void* info) { + CleanUpData* entry = fCleanUpData.push(); + + entry->fFunc = cleanUp; + entry->fInfo = info; + } + + /** + * Abandons all GPU resources and assumes the underlying backend 3D API context is not longer + * usable. Call this if you have lost the associated GPU context, and thus internal texture, + * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the + * GrContext and any of its created resource objects will not make backend 3D API calls. Content + * rendered but not previously flushed may be lost. After this function is called all subsequent + * calls on the GrContext will fail or be no-ops. + * + * The typical use case for this function is that the underlying 3D context was lost and further + * API calls may crash. + */ + void abandonContext(); + + /** + * This is similar to abandonContext() however the underlying 3D context is not yet lost and + * the GrContext will cleanup all allocated resources before returning. After returning it will + * assume that the underlying context may no longer be valid. + * + * The typical use case for this function is that the client is going to destroy the 3D context + * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed + * elsewhere by either the client or Skia objects). + */ + void releaseResourcesAndAbandonContext(); + + /////////////////////////////////////////////////////////////////////////// + // Resource Cache + + /** + * Return the current GPU resource cache limits. + * + * @param maxResources If non-null, returns maximum number of resources that + * can be held in the cache. + * @param maxResourceBytes If non-null, returns maximum number of bytes of + * video memory that can be held in the cache. + */ + void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const; + + /** + * Gets the current GPU resource cache usage. + * + * @param resourceCount If non-null, returns the number of resources that are held in the + * cache. + * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held + * in the cache. + */ + void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const; + + /** + * Specify the GPU resource cache limits. If the current cache exceeds either + * of these, it will be purged (LRU) to keep the cache within these limits. + * + * @param maxResources The maximum number of resources that can be held in + * the cache. + * @param maxResourceBytes The maximum number of bytes of video memory + * that can be held in the cache. + */ + void setResourceCacheLimits(int maxResources, size_t maxResourceBytes); + + GrTextureProvider* textureProvider() { return fTextureProvider; } + const GrTextureProvider* textureProvider() const { return fTextureProvider; } + + /** + * Frees GPU created by the context. Can be called to reduce GPU memory + * pressure. + */ + void freeGpuResources(); + + /** + * Purge all the unlocked resources from the cache. + * This entry point is mainly meant for timing texture uploads + * and is not defined in normal builds of Skia. + */ + void purgeAllUnlockedResources(); + + /** Access the context capabilities */ + const GrCaps* caps() const { return fCaps; } + + /** + * Returns the recommended sample count for a render target when using this + * context. + * + * @param config the configuration of the render target. + * @param dpi the display density in dots per inch. + * + * @return sample count that should be perform well and have good enough + * rendering quality for the display. Alternatively returns 0 if + * MSAA is not supported or recommended to be used by default. + */ + int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; + + /** + * Create both a GrRenderTarget and a matching GrDrawContext to wrap it. + * We guarantee that "asTexture" will succeed for drawContexts created + * via this entry point. + */ + sk_sp<GrDrawContext> makeDrawContext(SkBackingFit fit, + int width, int height, + GrPixelConfig config, + sk_sp<SkColorSpace> colorSpace, + int sampleCnt = 0, + GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin, + const SkSurfaceProps* surfaceProps = nullptr, + SkBudgeted = SkBudgeted::kYes); + + /* + * This method will attempt to create a drawContext that has, at least, the number of + * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be + * converted to 8888). It may also swizzle the channels (e.g., BGRA -> RGBA). + * SRGB-ness will be preserved. + */ + sk_sp<GrDrawContext> makeDrawContextWithFallback( + SkBackingFit fit, + int width, int height, + GrPixelConfig config, + sk_sp<SkColorSpace> colorSpace, + int sampleCnt = 0, + GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin, + const SkSurfaceProps* surfaceProps = nullptr, + SkBudgeted budgeted = SkBudgeted::kYes); + + /////////////////////////////////////////////////////////////////////////// + // Misc. + + /** + * Call to ensure all drawing to the context has been issued to the + * underlying 3D API. + */ + void flush(); + + /** + * These flags can be used with the read/write pixels functions below. + */ + enum PixelOpsFlags { + /** The GrContext will not be flushed before the surface read or write. This means that + the read or write may occur before previous draws have executed. */ + kDontFlush_PixelOpsFlag = 0x1, + /** Any surface writes should be flushed to the backend 3D API after the surface operation + is complete */ + kFlushWrites_PixelOp = 0x2, + /** The src for write or dst read is unpremultiplied. This is only respected if both the + config src and dst configs are an RGBA/BGRA 8888 format. */ + kUnpremul_PixelOpsFlag = 0x4, + }; + + /** + * Reads a rectangle of pixels from a surface. + * @param surface the surface to read from. + * @param left left edge of the rectangle to read (inclusive) + * @param top top edge of the rectangle to read (inclusive) + * @param width width of rectangle to read in pixels. + * @param height height of rectangle to read in pixels. + * @param config the pixel config of the destination buffer + * @param buffer memory to read the rectangle into. + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly + * packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. + * + * @return true if the read succeeded, false if not. The read can fail because of an unsupported + * pixel configs + */ + bool readSurfacePixels(GrSurface* surface, + int left, int top, int width, int height, + GrPixelConfig config, void* buffer, + size_t rowBytes = 0, + uint32_t pixelOpsFlags = 0); + + /** + * Writes a rectangle of pixels to a surface. + * @param surface the surface to write to. + * @param left left edge of the rectangle to write (inclusive) + * @param top top edge of the rectangle to write (inclusive) + * @param width width of rectangle to write in pixels. + * @param height height of rectangle to write in pixels. + * @param config the pixel config of the source buffer + * @param buffer memory to read pixels from + * @param rowBytes number of bytes between consecutive rows. Zero + * means rows are tightly packed. + * @param pixelOpsFlags see PixelOpsFlags enum above. + * @return true if the write succeeded, false if not. The write can fail because of an + * unsupported combination of surface and src configs. + */ + bool writeSurfacePixels(GrSurface* surface, + int left, int top, int width, int height, + GrPixelConfig config, const void* buffer, + size_t rowBytes, + uint32_t pixelOpsFlags = 0); + + /** + * Copies a rectangle of texels from src to dst. + * @param dst the surface to copy to. + * @param src the surface to copy from. + * @param srcRect the rectangle of the src that should be copied. + * @param dstPoint the translation applied when writing the srcRect's pixels to the dst. + */ + bool copySurface(GrSurface* dst, + GrSurface* src, + const SkIRect& srcRect, + const SkIPoint& dstPoint); + + /** Helper that copies the whole surface but fails when the two surfaces are not identically + sized. */ + bool copySurface(GrSurface* dst, GrSurface* src) { + return this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()), + SkIPoint::Make(0,0)); + } + + /** + * After this returns any pending writes to the surface will have been issued to the backend 3D API. + */ + void flushSurfaceWrites(GrSurface* surface); + + /** + * After this returns any pending reads or writes to the surface will have been issued to the + * backend 3D API. + */ + void flushSurfaceIO(GrSurface* surface); + + /** + * Finalizes all pending reads and writes to the surface and also performs an MSAA resolve + * if necessary. + * + * It is not necessary to call this before reading the render target via Skia/GrContext. + * GrContext will detect when it must perform a resolve before reading pixels back from the + * surface or using it as a texture. + */ + void prepareSurfaceForExternalIO(GrSurface*); + + /** + * An ID associated with this context, guaranteed to be unique. + */ + uint32_t uniqueID() { return fUniqueID; } + + /////////////////////////////////////////////////////////////////////////// + // Functions intended for internal use only. + GrGpu* getGpu() { return fGpu; } + const GrGpu* getGpu() const { return fGpu; } + GrBatchFontCache* getBatchFontCache() { return fBatchFontCache; } + GrTextBlobCache* getTextBlobCache() { return fTextBlobCache; } + bool abandoned() const; + GrResourceProvider* resourceProvider() { return fResourceProvider; } + const GrResourceProvider* resourceProvider() const { return fResourceProvider; } + GrResourceCache* getResourceCache() { return fResourceCache; } + + // Called by tests that draw directly to the context via GrDrawContext + void getTestTarget(GrTestTarget*, sk_sp<GrDrawContext>); + + /** Reset GPU stats */ + void resetGpuStats() const ; + + /** Prints cache stats to the string if GR_CACHE_STATS == 1. */ + void dumpCacheStats(SkString*) const; + void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; + void printCacheStats() const; + + /** Prints GPU stats to the string if GR_GPU_STATS == 1. */ + void dumpGpuStats(SkString*) const; + void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const; + void printGpuStats() const; + + /** Specify the TextBlob cache limit. If the current cache exceeds this limit it will purge. + this is for testing only */ + void setTextBlobCacheLimit_ForTesting(size_t bytes); + + /** Specify the sizes of the GrAtlasTextContext atlases. The configs pointer below should be + to an array of 3 entries */ + void setTextContextAtlasSizes_ForTesting(const GrBatchAtlasConfig* configs); + + /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */ + void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const; + + /** Get pointer to atlas texture for given mask format */ + GrTexture* getFontAtlasTexture(GrMaskFormat format); + + GrAuditTrail* getAuditTrail() { return &fAuditTrail; } + + /** This is only useful for debug purposes */ + SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } ) + + // Provides access to functions that aren't part of the public API. + GrContextPriv contextPriv(); + const GrContextPriv contextPriv() const; + +private: + GrGpu* fGpu; + const GrCaps* fCaps; + GrResourceCache* fResourceCache; + // this union exists because the inheritance of GrTextureProvider->GrResourceProvider + // is in a private header. + union { + GrResourceProvider* fResourceProvider; + GrTextureProvider* fTextureProvider; + }; + + SkAutoTUnref<GrContextThreadSafeProxy> fThreadSafeProxy; + + GrBatchFontCache* fBatchFontCache; + SkAutoTDelete<GrTextBlobCache> fTextBlobCache; + + bool fDidTestPMConversions; + int fPMToUPMConversion; + int fUPMToPMConversion; + // The sw backend may call GrContext::readSurfacePixels on multiple threads + // We may transfer the responsibilty for using a mutex to the sw backend + // when there are fewer code paths that lead to a readSurfacePixels call + // from the sw backend. readSurfacePixels is reentrant in one case - when performing + // the PM conversions test. To handle this we do the PM conversions test outside + // of fReadPixelsMutex and use a separate mutex to guard it. When it re-enters + // readSurfacePixels it will grab fReadPixelsMutex and release it before the outer + // readSurfacePixels proceeds to grab it. + // TODO: Stop pretending to make GrContext thread-safe for sw rasterization and provide + // a mechanism to make a SkPicture safe for multithreaded sw rasterization. + SkMutex fReadPixelsMutex; + SkMutex fTestPMConversionsMutex; + + // In debug builds we guard against improper thread handling + // This guard is passed to the GrDrawingManager and, from there to all the + // GrDrawContexts. It is also passed to the GrTextureProvider and SkGpuDevice. + mutable GrSingleOwner fSingleOwner; + + struct CleanUpData { + PFCleanUpFunc fFunc; + void* fInfo; + }; + + SkTDArray<CleanUpData> fCleanUpData; + + const uint32_t fUniqueID; + + SkAutoTDelete<GrDrawingManager> fDrawingManager; + + GrAuditTrail fAuditTrail; + + // TODO: have the GrClipStackClip use drawContexts and rm this friending + friend class GrContextPriv; + + GrContext(); // init must be called after the constructor. + bool init(GrBackend, GrBackendContext, const GrContextOptions& options); + + void initMockContext(); + void initCommon(const GrContextOptions&); + + /** + * These functions create premul <-> unpremul effects if it is possible to generate a pair + * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they + * return NULL. They also can perform a swizzle as part of the draw. + */ + sk_sp<GrFragmentProcessor> createPMToUPMEffect(GrTexture*, const GrSwizzle&, + const SkMatrix&) const; + sk_sp<GrFragmentProcessor> createUPMToPMEffect(GrTexture*, const GrSwizzle&, + const SkMatrix&) const; + /** Called before either of the above two functions to determine the appropriate fragment + processors for conversions. This must be called by readSurfacePixels before a mutex is + taken, since testingvPM conversions itself will call readSurfacePixels */ + void testPMConversionsIfNecessary(uint32_t flags); + /** Returns true if we've already determined that createPMtoUPMEffect and createUPMToPMEffect + will fail. In such cases fall back to SW conversion. */ + bool didFailPMUPMConversionTest() const; + + /** + * A callback similar to the above for use by the TextBlobCache + * TODO move textblob draw calls below context so we can use the call above. + */ + static void TextBlobCacheOverBudgetCB(void* data); + + typedef SkRefCnt INHERITED; +}; + +/** + * Can be used to perform actions related to the generating GrContext in a thread safe manner. The + * proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext. + */ +class GrContextThreadSafeProxy : public SkRefCnt { +private: + GrContextThreadSafeProxy(const GrCaps* caps, uint32_t uniqueID) + : fCaps(SkRef(caps)) + , fContextUniqueID(uniqueID) {} + + SkAutoTUnref<const GrCaps> fCaps; + uint32_t fContextUniqueID; + + friend class GrContext; + friend class SkImage; + + typedef SkRefCnt INHERITED; +}; + +#endif |