1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/gpu/GrContext.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1066 @@ 1.4 +/* 1.5 + * Copyright 2010 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrContext_DEFINED 1.12 +#define GrContext_DEFINED 1.13 + 1.14 +#include "GrClipData.h" 1.15 +#include "GrColor.h" 1.16 +#include "GrPaint.h" 1.17 +#include "GrPathRendererChain.h" 1.18 +#include "GrPoint.h" 1.19 +#include "GrRenderTarget.h" 1.20 +#include "GrTexture.h" 1.21 +#include "SkMatrix.h" 1.22 +#include "SkTypes.h" 1.23 + 1.24 +class GrAARectRenderer; 1.25 +class GrAutoScratchTexture; 1.26 +class GrDrawState; 1.27 +class GrDrawTarget; 1.28 +class GrEffect; 1.29 +class GrFontCache; 1.30 +class GrGpu; 1.31 +class GrIndexBuffer; 1.32 +class GrIndexBufferAllocPool; 1.33 +class GrInOrderDrawBuffer; 1.34 +class GrOvalRenderer; 1.35 +class GrPath; 1.36 +class GrPathRenderer; 1.37 +class GrResourceEntry; 1.38 +class GrResourceCache; 1.39 +class GrStencilBuffer; 1.40 +class GrTestTarget; 1.41 +class GrTextureParams; 1.42 +class GrVertexBuffer; 1.43 +class GrVertexBufferAllocPool; 1.44 +class GrSoftwarePathRenderer; 1.45 +class SkStrokeRec; 1.46 + 1.47 +class SK_API GrContext : public SkRefCnt { 1.48 +public: 1.49 + SK_DECLARE_INST_COUNT(GrContext) 1.50 + 1.51 + /** 1.52 + * Creates a GrContext for a backend context. 1.53 + */ 1.54 + static GrContext* Create(GrBackend, GrBackendContext); 1.55 + 1.56 + virtual ~GrContext(); 1.57 + 1.58 + /** 1.59 + * The GrContext normally assumes that no outsider is setting state 1.60 + * within the underlying 3D API's context/device/whatever. This call informs 1.61 + * the context that the state was modified and it should resend. Shouldn't 1.62 + * be called frequently for good performance. 1.63 + * The flag bits, state, is dpendent on which backend is used by the 1.64 + * context, either GL or D3D (possible in future). 1.65 + */ 1.66 + void resetContext(uint32_t state = kAll_GrBackendState); 1.67 + 1.68 + /** 1.69 + * Callback function to allow classes to cleanup on GrContext destruction. 1.70 + * The 'info' field is filled in with the 'info' passed to addCleanUp. 1.71 + */ 1.72 + typedef void (*PFCleanUpFunc)(const GrContext* context, void* info); 1.73 + 1.74 + /** 1.75 + * Add a function to be called from within GrContext's destructor. 1.76 + * This gives classes a chance to free resources held on a per context basis. 1.77 + * The 'info' parameter will be stored and passed to the callback function. 1.78 + */ 1.79 + void addCleanUp(PFCleanUpFunc cleanUp, void* info) { 1.80 + CleanUpData* entry = fCleanUpData.push(); 1.81 + 1.82 + entry->fFunc = cleanUp; 1.83 + entry->fInfo = info; 1.84 + } 1.85 + 1.86 + /** 1.87 + * Abandons all GPU resources, assumes 3D API state is unknown. Call this 1.88 + * if you have lost the associated GPU context, and thus internal texture, 1.89 + * buffer, etc. references/IDs are now invalid. Should be called even when 1.90 + * GrContext is no longer going to be used for two reasons: 1.91 + * 1) ~GrContext will not try to free the objects in the 3D API. 1.92 + * 2) If you've created GrResources that outlive the GrContext they will 1.93 + * be marked as invalid (GrResource::isValid()) and won't attempt to 1.94 + * free their underlying resource in the 3D API. 1.95 + * Content drawn since the last GrContext::flush() may be lost. 1.96 + */ 1.97 + void contextLost(); 1.98 + 1.99 + /** 1.100 + * Similar to contextLost, but makes no attempt to reset state. 1.101 + * Use this method when GrContext destruction is pending, but 1.102 + * the graphics context is destroyed first. 1.103 + */ 1.104 + void contextDestroyed(); 1.105 + 1.106 + /** 1.107 + * Frees GPU created by the context. Can be called to reduce GPU memory 1.108 + * pressure. 1.109 + */ 1.110 + void freeGpuResources(); 1.111 + 1.112 + /** 1.113 + * Returns the number of bytes of GPU memory hosted by the texture cache. 1.114 + */ 1.115 + size_t getGpuTextureCacheBytes() const; 1.116 + 1.117 + /////////////////////////////////////////////////////////////////////////// 1.118 + // Textures 1.119 + 1.120 + /** 1.121 + * Creates a new entry, based on the specified key and texture and returns it. The caller owns a 1.122 + * ref on the returned texture which must be balanced by a call to unref. 1.123 + * 1.124 + * @param params The texture params used to draw a texture may help determine 1.125 + * the cache entry used. (e.g. different versions may exist 1.126 + * for different wrap modes on GPUs with limited NPOT 1.127 + * texture support). NULL implies clamp wrap modes. 1.128 + * @param desc Description of the texture properties. 1.129 + * @param cacheID Cache-specific properties (e.g., texture gen ID) 1.130 + * @param srcData Pointer to the pixel values. 1.131 + * @param rowBytes The number of bytes between rows of the texture. Zero 1.132 + * implies tightly packed rows. 1.133 + * @param cacheKey (optional) If non-NULL, we'll write the cache key we used to cacheKey. 1.134 + */ 1.135 + GrTexture* createTexture(const GrTextureParams* params, 1.136 + const GrTextureDesc& desc, 1.137 + const GrCacheID& cacheID, 1.138 + void* srcData, 1.139 + size_t rowBytes, 1.140 + GrResourceKey* cacheKey = NULL); 1.141 + 1.142 + /** 1.143 + * Search for an entry based on key and dimensions. If found, ref it and return it. The return 1.144 + * value will be NULL if not found. The caller must balance with a call to unref. 1.145 + * 1.146 + * @param desc Description of the texture properties. 1.147 + * @param cacheID Cache-specific properties (e.g., texture gen ID) 1.148 + * @param params The texture params used to draw a texture may help determine 1.149 + * the cache entry used. (e.g. different versions may exist 1.150 + * for different wrap modes on GPUs with limited NPOT 1.151 + * texture support). NULL implies clamp wrap modes. 1.152 + */ 1.153 + GrTexture* findAndRefTexture(const GrTextureDesc& desc, 1.154 + const GrCacheID& cacheID, 1.155 + const GrTextureParams* params); 1.156 + /** 1.157 + * Determines whether a texture is in the cache. If the texture is found it 1.158 + * will not be locked or returned. This call does not affect the priority of 1.159 + * the texture for deletion. 1.160 + */ 1.161 + bool isTextureInCache(const GrTextureDesc& desc, 1.162 + const GrCacheID& cacheID, 1.163 + const GrTextureParams* params) const; 1.164 + 1.165 + /** 1.166 + * Enum that determines how closely a returned scratch texture must match 1.167 + * a provided GrTextureDesc. 1.168 + */ 1.169 + enum ScratchTexMatch { 1.170 + /** 1.171 + * Finds a texture that exactly matches the descriptor. 1.172 + */ 1.173 + kExact_ScratchTexMatch, 1.174 + /** 1.175 + * Finds a texture that approximately matches the descriptor. Will be 1.176 + * at least as large in width and height as desc specifies. If desc 1.177 + * specifies that texture is a render target then result will be a 1.178 + * render target. If desc specifies a render target and doesn't set the 1.179 + * no stencil flag then result will have a stencil. Format and aa level 1.180 + * will always match. 1.181 + */ 1.182 + kApprox_ScratchTexMatch 1.183 + }; 1.184 + 1.185 + /** 1.186 + * Returns a texture matching the desc. It's contents are unknown. Subsequent 1.187 + * requests with the same descriptor are not guaranteed to return the same 1.188 + * texture. The same texture is guaranteed not be returned again until it is 1.189 + * unlocked. Call must be balanced with an unlockTexture() call. The caller 1.190 + * owns a ref on the returned texture and must balance with a call to unref. 1.191 + * 1.192 + * Textures created by createAndLockTexture() hide the complications of 1.193 + * tiling non-power-of-two textures on APIs that don't support this (e.g. 1.194 + * unextended GLES2). Tiling a NPOT texture created by lockScratchTexture on 1.195 + * such an API will create gaps in the tiling pattern. This includes clamp 1.196 + * mode. (This may be addressed in a future update.) 1.197 + */ 1.198 + GrTexture* lockAndRefScratchTexture(const GrTextureDesc&, ScratchTexMatch match); 1.199 + 1.200 + /** 1.201 + * When done with an entry, call unlockScratchTexture(entry) on it, which returns 1.202 + * it to the cache, where it may be purged. This does not unref the texture. 1.203 + */ 1.204 + void unlockScratchTexture(GrTexture* texture); 1.205 + 1.206 + /** 1.207 + * This method should be called whenever a GrTexture is unreffed or 1.208 + * switched from exclusive to non-exclusive. This 1.209 + * gives the resource cache a chance to discard unneeded textures. 1.210 + * Note: this entry point will be removed once totally ref-driven 1.211 + * cache maintenance is implemented 1.212 + */ 1.213 + void purgeCache(); 1.214 + 1.215 + /** 1.216 + * Purge all the unlocked resources from the cache. 1.217 + * This entry point is mainly meant for timing texture uploads 1.218 + * and is not defined in normal builds of Skia. 1.219 + */ 1.220 + void purgeAllUnlockedResources(); 1.221 + 1.222 + /** 1.223 + * Creates a texture that is outside the cache. Does not count against 1.224 + * cache's budget. 1.225 + */ 1.226 + GrTexture* createUncachedTexture(const GrTextureDesc& desc, 1.227 + void* srcData, 1.228 + size_t rowBytes); 1.229 + 1.230 + /** 1.231 + * Returns true if the specified use of an indexed texture is supported. 1.232 + * Support may depend upon whether the texture params indicate that the 1.233 + * texture will be tiled. Passing NULL for the texture params indicates 1.234 + * clamp mode. 1.235 + */ 1.236 + bool supportsIndex8PixelConfig(const GrTextureParams*, 1.237 + int width, 1.238 + int height) const; 1.239 + 1.240 + /** 1.241 + * Return the current texture cache limits. 1.242 + * 1.243 + * @param maxTextures If non-null, returns maximum number of textures that 1.244 + * can be held in the cache. 1.245 + * @param maxTextureBytes If non-null, returns maximum number of bytes of 1.246 + * texture memory that can be held in the cache. 1.247 + */ 1.248 + void getTextureCacheLimits(int* maxTextures, size_t* maxTextureBytes) const; 1.249 + 1.250 + /** 1.251 + * Specify the texture cache limits. If the current cache exceeds either 1.252 + * of these, it will be purged (LRU) to keep the cache within these limits. 1.253 + * 1.254 + * @param maxTextures The maximum number of textures that can be held in 1.255 + * the cache. 1.256 + * @param maxTextureBytes The maximum number of bytes of texture memory 1.257 + * that can be held in the cache. 1.258 + */ 1.259 + void setTextureCacheLimits(int maxTextures, size_t maxTextureBytes); 1.260 + 1.261 + /** 1.262 + * Return the max width or height of a texture supported by the current GPU. 1.263 + */ 1.264 + int getMaxTextureSize() const; 1.265 + 1.266 + /** 1.267 + * Temporarily override the true max texture size. Note: an override 1.268 + * larger then the true max texture size will have no effect. 1.269 + * This entry point is mainly meant for testing texture size dependent 1.270 + * features and is only available if defined outside of Skia (see 1.271 + * bleed GM. 1.272 + */ 1.273 + void setMaxTextureSizeOverride(int maxTextureSizeOverride); 1.274 + 1.275 + /////////////////////////////////////////////////////////////////////////// 1.276 + // Render targets 1.277 + 1.278 + /** 1.279 + * Sets the render target. 1.280 + * @param target the render target to set. 1.281 + */ 1.282 + void setRenderTarget(GrRenderTarget* target) { 1.283 + fRenderTarget.reset(SkSafeRef(target)); 1.284 + } 1.285 + 1.286 + /** 1.287 + * Gets the current render target. 1.288 + * @return the currently bound render target. 1.289 + */ 1.290 + const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } 1.291 + GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } 1.292 + 1.293 + GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; } 1.294 + 1.295 + /** 1.296 + * Can the provided configuration act as a color render target? 1.297 + */ 1.298 + bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const; 1.299 + 1.300 + /** 1.301 + * Return the max width or height of a render target supported by the 1.302 + * current GPU. 1.303 + */ 1.304 + int getMaxRenderTargetSize() const; 1.305 + 1.306 + /** 1.307 + * Returns the max sample count for a render target. It will be 0 if MSAA 1.308 + * is not supported. 1.309 + */ 1.310 + int getMaxSampleCount() const; 1.311 + 1.312 + /** 1.313 + * Returns the recommended sample count for a render target when using this 1.314 + * context. 1.315 + * 1.316 + * @param config the configuration of the render target. 1.317 + * @param dpi the display density in dots per inch. 1.318 + * 1.319 + * @return sample count that should be perform well and have good enough 1.320 + * rendering quality for the display. Alternatively returns 0 if 1.321 + * MSAA is not supported or recommended to be used by default. 1.322 + */ 1.323 + int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; 1.324 + 1.325 + /////////////////////////////////////////////////////////////////////////// 1.326 + // Backend Surfaces 1.327 + 1.328 + /** 1.329 + * Wraps an existing texture with a GrTexture object. 1.330 + * 1.331 + * OpenGL: if the object is a texture Gr may change its GL texture params 1.332 + * when it is drawn. 1.333 + * 1.334 + * @param desc description of the object to create. 1.335 + * 1.336 + * @return GrTexture object or NULL on failure. 1.337 + */ 1.338 + GrTexture* wrapBackendTexture(const GrBackendTextureDesc& desc); 1.339 + 1.340 + /** 1.341 + * Wraps an existing render target with a GrRenderTarget object. It is 1.342 + * similar to wrapBackendTexture but can be used to draw into surfaces 1.343 + * that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that 1.344 + * the client will resolve to a texture). 1.345 + * 1.346 + * @param desc description of the object to create. 1.347 + * 1.348 + * @return GrTexture object or NULL on failure. 1.349 + */ 1.350 + GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc); 1.351 + 1.352 + /////////////////////////////////////////////////////////////////////////// 1.353 + // Matrix state 1.354 + 1.355 + /** 1.356 + * Gets the current transformation matrix. 1.357 + * @return the current matrix. 1.358 + */ 1.359 + const SkMatrix& getMatrix() const { return fViewMatrix; } 1.360 + 1.361 + /** 1.362 + * Sets the transformation matrix. 1.363 + * @param m the matrix to set. 1.364 + */ 1.365 + void setMatrix(const SkMatrix& m) { fViewMatrix = m; } 1.366 + 1.367 + /** 1.368 + * Sets the current transformation matrix to identity. 1.369 + */ 1.370 + void setIdentityMatrix() { fViewMatrix.reset(); } 1.371 + 1.372 + /** 1.373 + * Concats the current matrix. The passed matrix is applied before the 1.374 + * current matrix. 1.375 + * @param m the matrix to concat. 1.376 + */ 1.377 + void concatMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); } 1.378 + 1.379 + 1.380 + /////////////////////////////////////////////////////////////////////////// 1.381 + // Clip state 1.382 + /** 1.383 + * Gets the current clip. 1.384 + * @return the current clip. 1.385 + */ 1.386 + const GrClipData* getClip() const { return fClip; } 1.387 + 1.388 + /** 1.389 + * Sets the clip. 1.390 + * @param clipData the clip to set. 1.391 + */ 1.392 + void setClip(const GrClipData* clipData) { fClip = clipData; } 1.393 + 1.394 + /////////////////////////////////////////////////////////////////////////// 1.395 + // Draws 1.396 + 1.397 + /** 1.398 + * Clear the entire or rect of the render target, ignoring any clips. 1.399 + * @param rect the rect to clear or the whole thing if rect is NULL. 1.400 + * @param color the color to clear to. 1.401 + * @param canIgnoreRect allows partial clears to be converted to whole 1.402 + * clears on platforms for which that is cheap 1.403 + * @param target if non-NULL, the render target to clear otherwise clear 1.404 + * the current render target 1.405 + */ 1.406 + void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, 1.407 + GrRenderTarget* target = NULL); 1.408 + 1.409 + /** 1.410 + * Draw everywhere (respecting the clip) with the paint. 1.411 + */ 1.412 + void drawPaint(const GrPaint& paint); 1.413 + 1.414 + /** 1.415 + * Draw the rect using a paint. 1.416 + * @param paint describes how to color pixels. 1.417 + * @param stroke the stroke information (width, join, cap). 1.418 + * If stroke == NULL, then the rect is filled. 1.419 + * Otherwise, if stroke width == 0, then the stroke 1.420 + * is always a single pixel thick, else the rect is 1.421 + * mitered/beveled stroked based on stroke width. 1.422 + * @param matrix Optional matrix applied to the rect. Applied before 1.423 + * context's matrix or the paint's matrix. 1.424 + * The rects coords are used to access the paint (through texture matrix) 1.425 + */ 1.426 + void drawRect(const GrPaint& paint, 1.427 + const SkRect&, 1.428 + const SkStrokeRec* stroke = NULL, 1.429 + const SkMatrix* matrix = NULL); 1.430 + 1.431 + /** 1.432 + * Maps a rect of local coordinates onto the a rect of destination 1.433 + * coordinates. Each rect can optionally be transformed. The localRect 1.434 + * is stretched over the dstRect. The dstRect is transformed by the 1.435 + * context's matrix. Additional optional matrices for both rects can be 1.436 + * provided by parameters. 1.437 + * 1.438 + * @param paint describes how to color pixels. 1.439 + * @param dstRect the destination rect to draw. 1.440 + * @param localRect rect of local coordinates to be mapped onto dstRect 1.441 + * @param dstMatrix Optional matrix to transform dstRect. Applied before context's matrix. 1.442 + * @param localMatrix Optional matrix to transform localRect. 1.443 + */ 1.444 + void drawRectToRect(const GrPaint& paint, 1.445 + const SkRect& dstRect, 1.446 + const SkRect& localRect, 1.447 + const SkMatrix* dstMatrix = NULL, 1.448 + const SkMatrix* localMatrix = NULL); 1.449 + 1.450 + /** 1.451 + * Draw a roundrect using a paint. 1.452 + * 1.453 + * @param paint describes how to color pixels. 1.454 + * @param rrect the roundrect to draw 1.455 + * @param stroke the stroke information (width, join, cap) 1.456 + */ 1.457 + void drawRRect(const GrPaint& paint, 1.458 + const SkRRect& rrect, 1.459 + const SkStrokeRec& stroke); 1.460 + 1.461 + /** 1.462 + * Draws a path. 1.463 + * 1.464 + * @param paint describes how to color pixels. 1.465 + * @param path the path to draw 1.466 + * @param stroke the stroke information (width, join, cap) 1.467 + */ 1.468 + void drawPath(const GrPaint& paint, const SkPath& path, const SkStrokeRec& stroke); 1.469 + 1.470 + /** 1.471 + * Draws vertices with a paint. 1.472 + * 1.473 + * @param paint describes how to color pixels. 1.474 + * @param primitiveType primitives type to draw. 1.475 + * @param vertexCount number of vertices. 1.476 + * @param positions array of vertex positions, required. 1.477 + * @param texCoords optional array of texture coordinates used 1.478 + * to access the paint. 1.479 + * @param colors optional array of per-vertex colors, supercedes 1.480 + * the paint's color field. 1.481 + * @param indices optional array of indices. If NULL vertices 1.482 + * are drawn non-indexed. 1.483 + * @param indexCount if indices is non-null then this is the 1.484 + * number of indices. 1.485 + */ 1.486 + void drawVertices(const GrPaint& paint, 1.487 + GrPrimitiveType primitiveType, 1.488 + int vertexCount, 1.489 + const GrPoint positions[], 1.490 + const GrPoint texs[], 1.491 + const GrColor colors[], 1.492 + const uint16_t indices[], 1.493 + int indexCount); 1.494 + 1.495 + /** 1.496 + * Draws an oval. 1.497 + * 1.498 + * @param paint describes how to color pixels. 1.499 + * @param oval the bounding rect of the oval. 1.500 + * @param stroke the stroke information (width, style) 1.501 + */ 1.502 + void drawOval(const GrPaint& paint, 1.503 + const SkRect& oval, 1.504 + const SkStrokeRec& stroke); 1.505 + 1.506 + /////////////////////////////////////////////////////////////////////////// 1.507 + // Misc. 1.508 + 1.509 + /** 1.510 + * Flags that affect flush() behavior. 1.511 + */ 1.512 + enum FlushBits { 1.513 + /** 1.514 + * A client may reach a point where it has partially rendered a frame 1.515 + * through a GrContext that it knows the user will never see. This flag 1.516 + * causes the flush to skip submission of deferred content to the 3D API 1.517 + * during the flush. 1.518 + */ 1.519 + kDiscard_FlushBit = 0x2, 1.520 + }; 1.521 + 1.522 + /** 1.523 + * Call to ensure all drawing to the context has been issued to the 1.524 + * underlying 3D API. 1.525 + * @param flagsBitfield flags that control the flushing behavior. See 1.526 + * FlushBits. 1.527 + */ 1.528 + void flush(int flagsBitfield = 0); 1.529 + 1.530 + /** 1.531 + * These flags can be used with the read/write pixels functions below. 1.532 + */ 1.533 + enum PixelOpsFlags { 1.534 + /** The GrContext will not be flushed. This means that the read or write may occur before 1.535 + previous draws have executed. */ 1.536 + kDontFlush_PixelOpsFlag = 0x1, 1.537 + /** The src for write or dst read is unpremultiplied. This is only respected if both the 1.538 + config src and dst configs are an RGBA/BGRA 8888 format. */ 1.539 + kUnpremul_PixelOpsFlag = 0x2, 1.540 + }; 1.541 + 1.542 + /** 1.543 + * Reads a rectangle of pixels from a render target. 1.544 + * @param target the render target to read from. NULL means the current render target. 1.545 + * @param left left edge of the rectangle to read (inclusive) 1.546 + * @param top top edge of the rectangle to read (inclusive) 1.547 + * @param width width of rectangle to read in pixels. 1.548 + * @param height height of rectangle to read in pixels. 1.549 + * @param config the pixel config of the destination buffer 1.550 + * @param buffer memory to read the rectangle into. 1.551 + * @param rowBytes number of bytes bewtween consecutive rows. Zero means rows are tightly 1.552 + * packed. 1.553 + * @param pixelOpsFlags see PixelOpsFlags enum above. 1.554 + * 1.555 + * @return true if the read succeeded, false if not. The read can fail because of an unsupported 1.556 + * pixel config or because no render target is currently set and NULL was passed for 1.557 + * target. 1.558 + */ 1.559 + bool readRenderTargetPixels(GrRenderTarget* target, 1.560 + int left, int top, int width, int height, 1.561 + GrPixelConfig config, void* buffer, 1.562 + size_t rowBytes = 0, 1.563 + uint32_t pixelOpsFlags = 0); 1.564 + 1.565 + /** 1.566 + * Copy the src pixels [buffer, row bytes, pixel config] into a render target at the specified 1.567 + * rectangle. 1.568 + * @param target the render target to write into. NULL means the current render target. 1.569 + * @param left left edge of the rectangle to write (inclusive) 1.570 + * @param top top edge of the rectangle to write (inclusive) 1.571 + * @param width width of rectangle to write in pixels. 1.572 + * @param height height of rectangle to write in pixels. 1.573 + * @param config the pixel config of the source buffer 1.574 + * @param buffer memory to read the rectangle from. 1.575 + * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly 1.576 + * packed. 1.577 + * @param pixelOpsFlags see PixelOpsFlags enum above. 1.578 + * 1.579 + * @return true if the write succeeded, false if not. The write can fail because of an 1.580 + * unsupported combination of target and pixel configs. 1.581 + */ 1.582 + bool writeRenderTargetPixels(GrRenderTarget* target, 1.583 + int left, int top, int width, int height, 1.584 + GrPixelConfig config, const void* buffer, 1.585 + size_t rowBytes = 0, 1.586 + uint32_t pixelOpsFlags = 0); 1.587 + 1.588 + /** 1.589 + * Reads a rectangle of pixels from a texture. 1.590 + * @param texture the texture to read from. 1.591 + * @param left left edge of the rectangle to read (inclusive) 1.592 + * @param top top edge of the rectangle to read (inclusive) 1.593 + * @param width width of rectangle to read in pixels. 1.594 + * @param height height of rectangle to read in pixels. 1.595 + * @param config the pixel config of the destination buffer 1.596 + * @param buffer memory to read the rectangle into. 1.597 + * @param rowBytes number of bytes between consecutive rows. Zero means rows are tightly 1.598 + * packed. 1.599 + * @param pixelOpsFlags see PixelOpsFlags enum above. 1.600 + * 1.601 + * @return true if the read succeeded, false if not. The read can fail because of an unsupported 1.602 + * pixel config. 1.603 + */ 1.604 + bool readTexturePixels(GrTexture* texture, 1.605 + int left, int top, int width, int height, 1.606 + GrPixelConfig config, void* buffer, 1.607 + size_t rowBytes = 0, 1.608 + uint32_t pixelOpsFlags = 0); 1.609 + 1.610 + /** 1.611 + * Writes a rectangle of pixels to a texture. 1.612 + * @param texture the render target to read from. 1.613 + * @param left left edge of the rectangle to write (inclusive) 1.614 + * @param top top edge of the rectangle to write (inclusive) 1.615 + * @param width width of rectangle to write in pixels. 1.616 + * @param height height of rectangle to write in pixels. 1.617 + * @param config the pixel config of the source buffer 1.618 + * @param buffer memory to read pixels from 1.619 + * @param rowBytes number of bytes between consecutive rows. Zero 1.620 + * means rows are tightly packed. 1.621 + * @param pixelOpsFlags see PixelOpsFlags enum above. 1.622 + * @return true if the write succeeded, false if not. The write can fail because of an 1.623 + * unsupported combination of texture and pixel configs. 1.624 + */ 1.625 + bool writeTexturePixels(GrTexture* texture, 1.626 + int left, int top, int width, int height, 1.627 + GrPixelConfig config, const void* buffer, 1.628 + size_t rowBytes, 1.629 + uint32_t pixelOpsFlags = 0); 1.630 + 1.631 + 1.632 + /** 1.633 + * Copies a rectangle of texels from src to dst. The size of dst is the size of the rectangle 1.634 + * copied and topLeft is the position of the rect in src. The rectangle is clipped to src's 1.635 + * bounds. 1.636 + * @param src the texture to copy from. 1.637 + * @param dst the render target to copy to. 1.638 + * @param topLeft the point in src that will be copied to the top-left of dst. If NULL, 1.639 + * (0, 0) will be used. 1.640 + */ 1.641 + void copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint* topLeft = NULL); 1.642 + 1.643 + /** 1.644 + * Resolves a render target that has MSAA. The intermediate MSAA buffer is 1.645 + * down-sampled to the associated GrTexture (accessible via 1.646 + * GrRenderTarget::asTexture()). Any pending draws to the render target will 1.647 + * be executed before the resolve. 1.648 + * 1.649 + * This is only necessary when a client wants to access the object directly 1.650 + * using the backend API directly. GrContext will detect when it must 1.651 + * perform a resolve to a GrTexture used as the source of a draw or before 1.652 + * reading pixels back from a GrTexture or GrRenderTarget. 1.653 + */ 1.654 + void resolveRenderTarget(GrRenderTarget* target); 1.655 + 1.656 +#ifdef SK_DEVELOPER 1.657 + void dumpFontCache() const; 1.658 +#endif 1.659 + 1.660 + /////////////////////////////////////////////////////////////////////////// 1.661 + // Helpers 1.662 + 1.663 + class AutoRenderTarget : public ::SkNoncopyable { 1.664 + public: 1.665 + AutoRenderTarget(GrContext* context, GrRenderTarget* target) { 1.666 + fPrevTarget = context->getRenderTarget(); 1.667 + SkSafeRef(fPrevTarget); 1.668 + context->setRenderTarget(target); 1.669 + fContext = context; 1.670 + } 1.671 + AutoRenderTarget(GrContext* context) { 1.672 + fPrevTarget = context->getRenderTarget(); 1.673 + SkSafeRef(fPrevTarget); 1.674 + fContext = context; 1.675 + } 1.676 + ~AutoRenderTarget() { 1.677 + if (NULL != fContext) { 1.678 + fContext->setRenderTarget(fPrevTarget); 1.679 + } 1.680 + SkSafeUnref(fPrevTarget); 1.681 + } 1.682 + private: 1.683 + GrContext* fContext; 1.684 + GrRenderTarget* fPrevTarget; 1.685 + }; 1.686 + 1.687 + /** 1.688 + * Save/restore the view-matrix in the context. It can optionally adjust a paint to account 1.689 + * for a coordinate system change. Here is an example of how the paint param can be used: 1.690 + * 1.691 + * A GrPaint is setup with GrEffects. The stages will have access to the pre-matrix source 1.692 + * geometry positions when the draw is executed. Later on a decision is made to transform the 1.693 + * geometry to device space on the CPU. The effects now need to know that the space in which 1.694 + * the geometry will be specified has changed. 1.695 + * 1.696 + * Note that when restore is called (or in the destructor) the context's matrix will be 1.697 + * restored. However, the paint will not be restored. The caller must make a copy of the 1.698 + * paint if necessary. Hint: use SkTCopyOnFirstWrite if the AutoMatrix is conditionally 1.699 + * initialized. 1.700 + */ 1.701 + class AutoMatrix : public ::SkNoncopyable { 1.702 + public: 1.703 + AutoMatrix() : fContext(NULL) {} 1.704 + 1.705 + ~AutoMatrix() { this->restore(); } 1.706 + 1.707 + /** 1.708 + * Initializes by pre-concat'ing the context's current matrix with the preConcat param. 1.709 + */ 1.710 + void setPreConcat(GrContext* context, const SkMatrix& preConcat, GrPaint* paint = NULL) { 1.711 + SkASSERT(NULL != context); 1.712 + 1.713 + this->restore(); 1.714 + 1.715 + fContext = context; 1.716 + fMatrix = context->getMatrix(); 1.717 + this->preConcat(preConcat, paint); 1.718 + } 1.719 + 1.720 + /** 1.721 + * Sets the context's matrix to identity. Returns false if the inverse matrix is required to 1.722 + * update a paint but the matrix cannot be inverted. 1.723 + */ 1.724 + bool setIdentity(GrContext* context, GrPaint* paint = NULL) { 1.725 + SkASSERT(NULL != context); 1.726 + 1.727 + this->restore(); 1.728 + 1.729 + if (NULL != paint) { 1.730 + if (!paint->localCoordChangeInverse(context->getMatrix())) { 1.731 + return false; 1.732 + } 1.733 + } 1.734 + fMatrix = context->getMatrix(); 1.735 + fContext = context; 1.736 + context->setIdentityMatrix(); 1.737 + return true; 1.738 + } 1.739 + 1.740 + /** 1.741 + * Replaces the context's matrix with a new matrix. Returns false if the inverse matrix is 1.742 + * required to update a paint but the matrix cannot be inverted. 1.743 + */ 1.744 + bool set(GrContext* context, const SkMatrix& newMatrix, GrPaint* paint = NULL) { 1.745 + if (NULL != paint) { 1.746 + if (!this->setIdentity(context, paint)) { 1.747 + return false; 1.748 + } 1.749 + this->preConcat(newMatrix, paint); 1.750 + } else { 1.751 + this->restore(); 1.752 + fContext = context; 1.753 + fMatrix = context->getMatrix(); 1.754 + context->setMatrix(newMatrix); 1.755 + } 1.756 + return true; 1.757 + } 1.758 + 1.759 + /** 1.760 + * If this has been initialized then the context's matrix will be further updated by 1.761 + * pre-concat'ing the preConcat param. The matrix that will be restored remains unchanged. 1.762 + * The paint is assumed to be relative to the context's matrix at the time this call is 1.763 + * made, not the matrix at the time AutoMatrix was first initialized. In other words, this 1.764 + * performs an incremental update of the paint. 1.765 + */ 1.766 + void preConcat(const SkMatrix& preConcat, GrPaint* paint = NULL) { 1.767 + if (NULL != paint) { 1.768 + paint->localCoordChange(preConcat); 1.769 + } 1.770 + fContext->concatMatrix(preConcat); 1.771 + } 1.772 + 1.773 + /** 1.774 + * Returns false if never initialized or the inverse matrix was required to update a paint 1.775 + * but the matrix could not be inverted. 1.776 + */ 1.777 + bool succeeded() const { return NULL != fContext; } 1.778 + 1.779 + /** 1.780 + * If this has been initialized then the context's original matrix is restored. 1.781 + */ 1.782 + void restore() { 1.783 + if (NULL != fContext) { 1.784 + fContext->setMatrix(fMatrix); 1.785 + fContext = NULL; 1.786 + } 1.787 + } 1.788 + 1.789 + private: 1.790 + GrContext* fContext; 1.791 + SkMatrix fMatrix; 1.792 + }; 1.793 + 1.794 + class AutoClip : public ::SkNoncopyable { 1.795 + public: 1.796 + // This enum exists to require a caller of the constructor to acknowledge that the clip will 1.797 + // initially be wide open. It also could be extended if there are other desirable initial 1.798 + // clip states. 1.799 + enum InitialClip { 1.800 + kWideOpen_InitialClip, 1.801 + }; 1.802 + 1.803 + AutoClip(GrContext* context, InitialClip initialState) 1.804 + : fContext(context) { 1.805 + SkASSERT(kWideOpen_InitialClip == initialState); 1.806 + fNewClipData.fClipStack = &fNewClipStack; 1.807 + 1.808 + fOldClip = context->getClip(); 1.809 + context->setClip(&fNewClipData); 1.810 + } 1.811 + 1.812 + AutoClip(GrContext* context, const SkRect& newClipRect) 1.813 + : fContext(context) 1.814 + , fNewClipStack(newClipRect) { 1.815 + fNewClipData.fClipStack = &fNewClipStack; 1.816 + 1.817 + fOldClip = fContext->getClip(); 1.818 + fContext->setClip(&fNewClipData); 1.819 + } 1.820 + 1.821 + ~AutoClip() { 1.822 + if (NULL != fContext) { 1.823 + fContext->setClip(fOldClip); 1.824 + } 1.825 + } 1.826 + private: 1.827 + GrContext* fContext; 1.828 + const GrClipData* fOldClip; 1.829 + 1.830 + SkClipStack fNewClipStack; 1.831 + GrClipData fNewClipData; 1.832 + }; 1.833 + 1.834 + class AutoWideOpenIdentityDraw { 1.835 + public: 1.836 + AutoWideOpenIdentityDraw(GrContext* ctx, GrRenderTarget* rt) 1.837 + : fAutoClip(ctx, AutoClip::kWideOpen_InitialClip) 1.838 + , fAutoRT(ctx, rt) { 1.839 + fAutoMatrix.setIdentity(ctx); 1.840 + // should never fail with no paint param. 1.841 + SkASSERT(fAutoMatrix.succeeded()); 1.842 + } 1.843 + 1.844 + private: 1.845 + AutoClip fAutoClip; 1.846 + AutoRenderTarget fAutoRT; 1.847 + AutoMatrix fAutoMatrix; 1.848 + }; 1.849 + 1.850 + /////////////////////////////////////////////////////////////////////////// 1.851 + // Functions intended for internal use only. 1.852 + GrGpu* getGpu() { return fGpu; } 1.853 + const GrGpu* getGpu() const { return fGpu; } 1.854 + GrFontCache* getFontCache() { return fFontCache; } 1.855 + GrDrawTarget* getTextTarget(); 1.856 + const GrIndexBuffer* getQuadIndexBuffer() const; 1.857 + 1.858 + // Called by tests that draw directly to the context via GrDrawTarget 1.859 + void getTestTarget(GrTestTarget*); 1.860 + 1.861 + /** 1.862 + * Stencil buffers add themselves to the cache using addStencilBuffer. findStencilBuffer is 1.863 + * called to check the cache for a SB that matches an RT's criteria. 1.864 + */ 1.865 + void addStencilBuffer(GrStencilBuffer* sb); 1.866 + GrStencilBuffer* findStencilBuffer(int width, int height, int sampleCnt); 1.867 + 1.868 + GrPathRenderer* getPathRenderer( 1.869 + const SkPath& path, 1.870 + const SkStrokeRec& stroke, 1.871 + const GrDrawTarget* target, 1.872 + bool allowSW, 1.873 + GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, 1.874 + GrPathRendererChain::StencilSupport* stencilSupport = NULL); 1.875 + 1.876 + 1.877 +#if GR_CACHE_STATS 1.878 + void printCacheStats() const; 1.879 +#endif 1.880 + 1.881 +private: 1.882 + // Used to indicate whether a draw should be performed immediately or queued in fDrawBuffer. 1.883 + enum BufferedDraw { 1.884 + kYes_BufferedDraw, 1.885 + kNo_BufferedDraw, 1.886 + }; 1.887 + BufferedDraw fLastDrawWasBuffered; 1.888 + 1.889 + GrGpu* fGpu; 1.890 + SkMatrix fViewMatrix; 1.891 + SkAutoTUnref<GrRenderTarget> fRenderTarget; 1.892 + const GrClipData* fClip; // TODO: make this ref counted 1.893 + GrDrawState* fDrawState; 1.894 + 1.895 + GrResourceCache* fTextureCache; 1.896 + GrFontCache* fFontCache; 1.897 + 1.898 + GrPathRendererChain* fPathRendererChain; 1.899 + GrSoftwarePathRenderer* fSoftwarePathRenderer; 1.900 + 1.901 + GrVertexBufferAllocPool* fDrawBufferVBAllocPool; 1.902 + GrIndexBufferAllocPool* fDrawBufferIBAllocPool; 1.903 + GrInOrderDrawBuffer* fDrawBuffer; 1.904 + 1.905 + // Set by OverbudgetCB() to request that GrContext flush before exiting a draw. 1.906 + bool fFlushToReduceCacheSize; 1.907 + 1.908 + GrAARectRenderer* fAARectRenderer; 1.909 + GrOvalRenderer* fOvalRenderer; 1.910 + 1.911 + bool fDidTestPMConversions; 1.912 + int fPMToUPMConversion; 1.913 + int fUPMToPMConversion; 1.914 + 1.915 + struct CleanUpData { 1.916 + PFCleanUpFunc fFunc; 1.917 + void* fInfo; 1.918 + }; 1.919 + 1.920 + SkTDArray<CleanUpData> fCleanUpData; 1.921 + 1.922 + int fMaxTextureSizeOverride; 1.923 + 1.924 + GrContext(); // init must be called after the constructor. 1.925 + bool init(GrBackend, GrBackendContext); 1.926 + 1.927 + void setupDrawBuffer(); 1.928 + 1.929 + class AutoRestoreEffects; 1.930 + class AutoCheckFlush; 1.931 + /// Sets the paint and returns the target to draw into. The paint can be NULL in which case the 1.932 + /// draw state is left unmodified. 1.933 + GrDrawTarget* prepareToDraw(const GrPaint*, BufferedDraw, AutoRestoreEffects*, AutoCheckFlush*); 1.934 + 1.935 + void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path, 1.936 + const SkStrokeRec& stroke); 1.937 + 1.938 + GrTexture* createResizedTexture(const GrTextureDesc& desc, 1.939 + const GrCacheID& cacheID, 1.940 + void* srcData, 1.941 + size_t rowBytes, 1.942 + bool filter); 1.943 + 1.944 + // Needed so GrTexture's returnToCache helper function can call 1.945 + // addExistingTextureToCache 1.946 + friend class GrTexture; 1.947 + friend class GrStencilAndCoverPathRenderer; 1.948 + 1.949 + // Add an existing texture to the texture cache. This is intended solely 1.950 + // for use with textures released from an GrAutoScratchTexture. 1.951 + void addExistingTextureToCache(GrTexture* texture); 1.952 + 1.953 + /** 1.954 + * These functions create premul <-> unpremul effects if it is possible to generate a pair 1.955 + * of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they 1.956 + * return NULL. 1.957 + */ 1.958 + const GrEffectRef* createPMToUPMEffect(GrTexture* texture, 1.959 + bool swapRAndB, 1.960 + const SkMatrix& matrix); 1.961 + const GrEffectRef* createUPMToPMEffect(GrTexture* texture, 1.962 + bool swapRAndB, 1.963 + const SkMatrix& matrix); 1.964 + 1.965 + /** 1.966 + * This callback allows the resource cache to callback into the GrContext 1.967 + * when the cache is still overbudget after a purge. 1.968 + */ 1.969 + static bool OverbudgetCB(void* data); 1.970 + 1.971 + /** Creates a new gpu path, based on the specified path and stroke and returns it. 1.972 + * The caller owns a ref on the returned path which must be balanced by a call to unref. 1.973 + * 1.974 + * @param skPath the path geometry. 1.975 + * @param stroke the path stroke. 1.976 + * @return a new path or NULL if the operation is not supported by the backend. 1.977 + */ 1.978 + GrPath* createPath(const SkPath& skPath, const SkStrokeRec& stroke); 1.979 + 1.980 + typedef SkRefCnt INHERITED; 1.981 +}; 1.982 + 1.983 +/** 1.984 + * Gets and locks a scratch texture from a descriptor using either exact or approximate criteria. 1.985 + * Unlocks texture in the destructor. 1.986 + */ 1.987 +class GrAutoScratchTexture : public ::SkNoncopyable { 1.988 +public: 1.989 + GrAutoScratchTexture() 1.990 + : fContext(NULL) 1.991 + , fTexture(NULL) { 1.992 + } 1.993 + 1.994 + GrAutoScratchTexture(GrContext* context, 1.995 + const GrTextureDesc& desc, 1.996 + GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) 1.997 + : fContext(NULL) 1.998 + , fTexture(NULL) { 1.999 + this->set(context, desc, match); 1.1000 + } 1.1001 + 1.1002 + ~GrAutoScratchTexture() { 1.1003 + this->reset(); 1.1004 + } 1.1005 + 1.1006 + void reset() { 1.1007 + if (NULL != fContext && NULL != fTexture) { 1.1008 + fContext->unlockScratchTexture(fTexture); 1.1009 + fTexture->unref(); 1.1010 + fTexture = NULL; 1.1011 + } 1.1012 + } 1.1013 + 1.1014 + /* 1.1015 + * When detaching a texture we do not unlock it in the texture cache but 1.1016 + * we do set the returnToCache flag. In this way the texture remains 1.1017 + * "locked" in the texture cache until it is freed and recycled in 1.1018 + * GrTexture::internal_dispose. In reality, the texture has been removed 1.1019 + * from the cache (because this is in AutoScratchTexture) and by not 1.1020 + * calling unlockScratchTexture we simply don't re-add it. It will be 1.1021 + * reattached in GrTexture::internal_dispose. 1.1022 + * 1.1023 + * Note that the caller is assumed to accept and manage the ref to the 1.1024 + * returned texture. 1.1025 + */ 1.1026 + GrTexture* detach() { 1.1027 + if (NULL == fTexture) { 1.1028 + return NULL; 1.1029 + } 1.1030 + GrTexture* texture = fTexture; 1.1031 + fTexture = NULL; 1.1032 + 1.1033 + // This GrAutoScratchTexture has a ref from lockAndRefScratchTexture, which we give up now. 1.1034 + // The cache also has a ref which we are lending to the caller of detach(). When the caller 1.1035 + // lets go of the ref and the ref count goes to 0 internal_dispose will see this flag is 1.1036 + // set and re-ref the texture, thereby restoring the cache's ref. 1.1037 + SkASSERT(texture->getRefCnt() > 1); 1.1038 + texture->setFlag((GrTextureFlags) GrTexture::kReturnToCache_FlagBit); 1.1039 + texture->unref(); 1.1040 + SkASSERT(NULL != texture->getCacheEntry()); 1.1041 + 1.1042 + return texture; 1.1043 + } 1.1044 + 1.1045 + GrTexture* set(GrContext* context, 1.1046 + const GrTextureDesc& desc, 1.1047 + GrContext::ScratchTexMatch match = GrContext::kApprox_ScratchTexMatch) { 1.1048 + this->reset(); 1.1049 + 1.1050 + fContext = context; 1.1051 + if (NULL != fContext) { 1.1052 + fTexture = fContext->lockAndRefScratchTexture(desc, match); 1.1053 + if (NULL == fTexture) { 1.1054 + fContext = NULL; 1.1055 + } 1.1056 + return fTexture; 1.1057 + } else { 1.1058 + return NULL; 1.1059 + } 1.1060 + } 1.1061 + 1.1062 + GrTexture* texture() { return fTexture; } 1.1063 + 1.1064 +private: 1.1065 + GrContext* fContext; 1.1066 + GrTexture* fTexture; 1.1067 +}; 1.1068 + 1.1069 +#endif