1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrGpu.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,528 @@ 1.4 +/* 1.5 + * Copyright 2011 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 GrGpu_DEFINED 1.12 +#define GrGpu_DEFINED 1.13 + 1.14 +#include "GrDrawTarget.h" 1.15 +#include "GrClipMaskManager.h" 1.16 +#include "SkPath.h" 1.17 + 1.18 +class GrContext; 1.19 +class GrIndexBufferAllocPool; 1.20 +class GrPath; 1.21 +class GrPathRenderer; 1.22 +class GrPathRendererChain; 1.23 +class GrResource; 1.24 +class GrStencilBuffer; 1.25 +class GrVertexBufferAllocPool; 1.26 + 1.27 +class GrGpu : public GrDrawTarget { 1.28 +public: 1.29 + 1.30 + /** 1.31 + * Additional blend coefficients for dual source blending, not exposed 1.32 + * through GrPaint/GrContext. 1.33 + */ 1.34 + enum ExtendedBlendCoeffs { 1.35 + // source 2 refers to second output color when 1.36 + // using dual source blending. 1.37 + kS2C_GrBlendCoeff = kPublicGrBlendCoeffCount, 1.38 + kIS2C_GrBlendCoeff, 1.39 + kS2A_GrBlendCoeff, 1.40 + kIS2A_GrBlendCoeff, 1.41 + 1.42 + kTotalGrBlendCoeffCount 1.43 + }; 1.44 + 1.45 + /** 1.46 + * Create an instance of GrGpu that matches the specified backend. If the requested backend is 1.47 + * not supported (at compile-time or run-time) this returns NULL. The context will not be 1.48 + * fully constructed and should not be used by GrGpu until after this function returns. 1.49 + */ 1.50 + static GrGpu* Create(GrBackend, GrBackendContext, GrContext* context); 1.51 + 1.52 + //////////////////////////////////////////////////////////////////////////// 1.53 + 1.54 + GrGpu(GrContext* context); 1.55 + virtual ~GrGpu(); 1.56 + 1.57 + GrContext* getContext() { return this->INHERITED::getContext(); } 1.58 + const GrContext* getContext() const { return this->INHERITED::getContext(); } 1.59 + 1.60 + /** 1.61 + * The GrGpu object normally assumes that no outsider is setting state 1.62 + * within the underlying 3D API's context/device/whatever. This call informs 1.63 + * the GrGpu that the state was modified and it shouldn't make assumptions 1.64 + * about the state. 1.65 + */ 1.66 + void markContextDirty(uint32_t state = kAll_GrBackendState) { 1.67 + fResetBits |= state; 1.68 + } 1.69 + 1.70 + void unimpl(const char[]); 1.71 + 1.72 + /** 1.73 + * Creates a texture object. If desc width or height is not a power of 1.74 + * two but underlying API requires a power of two texture then srcData 1.75 + * will be embedded in a power of two texture. The extra width and height 1.76 + * is filled as though srcData were rendered clamped into the texture. 1.77 + * 1.78 + * If kRenderTarget_TextureFlag is specified the GrRenderTarget is 1.79 + * accessible via GrTexture::asRenderTarget(). The texture will hold a ref 1.80 + * on the render target until the texture is destroyed. 1.81 + * 1.82 + * @param desc describes the texture to be created. 1.83 + * @param srcData texel data to load texture. Begins with full-size 1.84 + * palette data for paletted textures. Contains width* 1.85 + * height texels. If NULL texture data is uninitialized. 1.86 + * 1.87 + * @return The texture object if successful, otherwise NULL. 1.88 + */ 1.89 + GrTexture* createTexture(const GrTextureDesc& desc, 1.90 + const void* srcData, size_t rowBytes); 1.91 + 1.92 + /** 1.93 + * Implements GrContext::wrapBackendTexture 1.94 + */ 1.95 + GrTexture* wrapBackendTexture(const GrBackendTextureDesc&); 1.96 + 1.97 + /** 1.98 + * Implements GrContext::wrapBackendTexture 1.99 + */ 1.100 + GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc&); 1.101 + 1.102 + /** 1.103 + * Creates a vertex buffer. 1.104 + * 1.105 + * @param size size in bytes of the vertex buffer 1.106 + * @param dynamic hints whether the data will be frequently changed 1.107 + * by either GrVertexBuffer::lock or 1.108 + * GrVertexBuffer::updateData. 1.109 + * 1.110 + * @return The vertex buffer if successful, otherwise NULL. 1.111 + */ 1.112 + GrVertexBuffer* createVertexBuffer(size_t size, bool dynamic); 1.113 + 1.114 + /** 1.115 + * Creates an index buffer. 1.116 + * 1.117 + * @param size size in bytes of the index buffer 1.118 + * @param dynamic hints whether the data will be frequently changed 1.119 + * by either GrIndexBuffer::lock or 1.120 + * GrIndexBuffer::updateData. 1.121 + * 1.122 + * @return The index buffer if successful, otherwise NULL. 1.123 + */ 1.124 + GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic); 1.125 + 1.126 + /** 1.127 + * Creates a path object that can be stenciled using stencilPath(). It is 1.128 + * only legal to call this if the caps report support for path stenciling. 1.129 + */ 1.130 + GrPath* createPath(const SkPath& path, const SkStrokeRec& stroke); 1.131 + 1.132 + /** 1.133 + * Returns an index buffer that can be used to render quads. 1.134 + * Six indices per quad: 0, 1, 2, 0, 2, 3, etc. 1.135 + * The max number of quads can be queried using GrIndexBuffer::maxQuads(). 1.136 + * Draw with kTriangles_GrPrimitiveType 1.137 + * @ return the quad index buffer 1.138 + */ 1.139 + const GrIndexBuffer* getQuadIndexBuffer() const; 1.140 + 1.141 + /** 1.142 + * Resolves MSAA. 1.143 + */ 1.144 + void resolveRenderTarget(GrRenderTarget* target); 1.145 + 1.146 + /** 1.147 + * Ensures that the current render target is actually set in the 1.148 + * underlying 3D API. Used when client wants to use 3D API to directly 1.149 + * render to the RT. 1.150 + */ 1.151 + void forceRenderTargetFlush(); 1.152 + 1.153 + /** 1.154 + * Gets a preferred 8888 config to use for writing/reading pixel data to/from a surface with 1.155 + * config surfaceConfig. The returned config must have at least as many bits per channel as the 1.156 + * readConfig or writeConfig param. 1.157 + */ 1.158 + virtual GrPixelConfig preferredReadPixelsConfig(GrPixelConfig readConfig, 1.159 + GrPixelConfig surfaceConfig) const { 1.160 + return readConfig; 1.161 + } 1.162 + virtual GrPixelConfig preferredWritePixelsConfig(GrPixelConfig writeConfig, 1.163 + GrPixelConfig surfaceConfig) const { 1.164 + return writeConfig; 1.165 + } 1.166 + 1.167 + /** 1.168 + * Called before uploading writing pixels to a GrTexture when the src pixel config doesn't 1.169 + * match the texture's config. 1.170 + */ 1.171 + virtual bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const = 0; 1.172 + 1.173 + /** 1.174 + * OpenGL's readPixels returns the result bottom-to-top while the skia 1.175 + * API is top-to-bottom. Thus we have to do a y-axis flip. The obvious 1.176 + * solution is to have the subclass do the flip using either the CPU or GPU. 1.177 + * However, the caller (GrContext) may have transformations to apply and can 1.178 + * simply fold in the y-flip for free. On the other hand, the subclass may 1.179 + * be able to do it for free itself. For example, the subclass may have to 1.180 + * do memcpys to handle rowBytes that aren't tight. It could do the y-flip 1.181 + * concurrently. 1.182 + * 1.183 + * This function returns true if a y-flip is required to put the pixels in 1.184 + * top-to-bottom order and the subclass cannot do it for free. 1.185 + * 1.186 + * See read pixels for the params 1.187 + * @return true if calling readPixels with the same set of params will 1.188 + * produce bottom-to-top data 1.189 + */ 1.190 + virtual bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget, 1.191 + int left, int top, 1.192 + int width, int height, 1.193 + GrPixelConfig config, 1.194 + size_t rowBytes) const = 0; 1.195 + /** 1.196 + * This should return true if reading a NxM rectangle of pixels from a 1.197 + * render target is faster if the target has dimensons N and M and the read 1.198 + * rectangle has its top-left at 0,0. 1.199 + */ 1.200 + virtual bool fullReadPixelsIsFasterThanPartial() const { return false; }; 1.201 + 1.202 + /** 1.203 + * Reads a rectangle of pixels from a render target. 1.204 + * 1.205 + * @param renderTarget the render target to read from. NULL means the 1.206 + * current render target. 1.207 + * @param left left edge of the rectangle to read (inclusive) 1.208 + * @param top top edge of the rectangle to read (inclusive) 1.209 + * @param width width of rectangle to read in pixels. 1.210 + * @param height height of rectangle to read in pixels. 1.211 + * @param config the pixel config of the destination buffer 1.212 + * @param buffer memory to read the rectangle into. 1.213 + * @param rowBytes the number of bytes between consecutive rows. Zero 1.214 + * means rows are tightly packed. 1.215 + * @param invertY buffer should be populated bottom-to-top as opposed 1.216 + * to top-to-bottom (skia's usual order) 1.217 + * 1.218 + * @return true if the read succeeded, false if not. The read can fail 1.219 + * because of a unsupported pixel config or because no render 1.220 + * target is currently set. 1.221 + */ 1.222 + bool readPixels(GrRenderTarget* renderTarget, 1.223 + int left, int top, int width, int height, 1.224 + GrPixelConfig config, void* buffer, size_t rowBytes); 1.225 + 1.226 + /** 1.227 + * Updates the pixels in a rectangle of a texture. 1.228 + * 1.229 + * @param left left edge of the rectangle to write (inclusive) 1.230 + * @param top top edge of the rectangle to write (inclusive) 1.231 + * @param width width of rectangle to write in pixels. 1.232 + * @param height height of rectangle to write in pixels. 1.233 + * @param config the pixel config of the source buffer 1.234 + * @param buffer memory to read pixels from 1.235 + * @param rowBytes number of bytes between consecutive rows. Zero 1.236 + * means rows are tightly packed. 1.237 + */ 1.238 + bool writeTexturePixels(GrTexture* texture, 1.239 + int left, int top, int width, int height, 1.240 + GrPixelConfig config, const void* buffer, 1.241 + size_t rowBytes); 1.242 + 1.243 + /** 1.244 + * Called to tell Gpu object that all GrResources have been lost and should 1.245 + * be abandoned. Overrides must call INHERITED::abandonResources(). 1.246 + */ 1.247 + virtual void abandonResources(); 1.248 + 1.249 + /** 1.250 + * Called to tell Gpu object to release all GrResources. Overrides must call 1.251 + * INHERITED::releaseResources(). 1.252 + */ 1.253 + void releaseResources(); 1.254 + 1.255 + /** 1.256 + * Add resource to list of resources. Should only be called by GrResource. 1.257 + * @param resource the resource to add. 1.258 + */ 1.259 + void insertResource(GrResource* resource); 1.260 + 1.261 + /** 1.262 + * Remove resource from list of resources. Should only be called by 1.263 + * GrResource. 1.264 + * @param resource the resource to remove. 1.265 + */ 1.266 + void removeResource(GrResource* resource); 1.267 + 1.268 + // GrDrawTarget overrides 1.269 + virtual void clear(const SkIRect* rect, 1.270 + GrColor color, 1.271 + bool canIgnoreRect, 1.272 + GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; 1.273 + 1.274 + virtual void purgeResources() SK_OVERRIDE { 1.275 + // The clip mask manager can rebuild all its clip masks so just 1.276 + // get rid of them all. 1.277 + fClipMaskManager.releaseResources(); 1.278 + } 1.279 + 1.280 + // After the client interacts directly with the 3D context state the GrGpu 1.281 + // must resync its internal state and assumptions about 3D context state. 1.282 + // Each time this occurs the GrGpu bumps a timestamp. 1.283 + // state of the 3D context 1.284 + // At 10 resets / frame and 60fps a 64bit timestamp will overflow in about 1.285 + // a billion years. 1.286 + typedef uint64_t ResetTimestamp; 1.287 + 1.288 + // This timestamp is always older than the current timestamp 1.289 + static const ResetTimestamp kExpiredTimestamp = 0; 1.290 + // Returns a timestamp based on the number of times the context was reset. 1.291 + // This timestamp can be used to lazily detect when cached 3D context state 1.292 + // is dirty. 1.293 + ResetTimestamp getResetTimestamp() const { 1.294 + return fResetTimestamp; 1.295 + } 1.296 + 1.297 + /** 1.298 + * These methods are called by the clip manager's setupClipping function 1.299 + * which (called as part of GrGpu's implementation of onDraw and 1.300 + * onStencilPath member functions.) The GrGpu subclass should flush the 1.301 + * stencil state to the 3D API in its implementation of flushGraphicsState. 1.302 + */ 1.303 + void enableScissor(const SkIRect& rect) { 1.304 + fScissorState.fEnabled = true; 1.305 + fScissorState.fRect = rect; 1.306 + } 1.307 + void disableScissor() { fScissorState.fEnabled = false; } 1.308 + 1.309 + /** 1.310 + * Like the scissor methods above this is called by setupClipping and 1.311 + * should be flushed by the GrGpu subclass in flushGraphicsState. These 1.312 + * stencil settings should be used in place of those on the GrDrawState. 1.313 + * They have been adjusted to account for any interactions between the 1.314 + * GrDrawState's stencil settings and stencil clipping. 1.315 + */ 1.316 + void setStencilSettings(const GrStencilSettings& settings) { 1.317 + fStencilSettings = settings; 1.318 + } 1.319 + void disableStencil() { fStencilSettings.setDisabled(); } 1.320 + 1.321 + // GrGpu subclass sets clip bit in the stencil buffer. The subclass is 1.322 + // free to clear the remaining bits to zero if masked clears are more 1.323 + // expensive than clearing all bits. 1.324 + virtual void clearStencilClip(const SkIRect& rect, bool insideClip) = 0; 1.325 + 1.326 + enum PrivateDrawStateStateBits { 1.327 + kFirstBit = (GrDrawState::kLastPublicStateBit << 1), 1.328 + 1.329 + kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify 1.330 + // stencil bits used for 1.331 + // clipping. 1.332 + }; 1.333 + 1.334 + void getPathStencilSettingsForFillType(SkPath::FillType fill, GrStencilSettings* outStencilSettings); 1.335 + 1.336 +protected: 1.337 + enum DrawType { 1.338 + kDrawPoints_DrawType, 1.339 + kDrawLines_DrawType, 1.340 + kDrawTriangles_DrawType, 1.341 + kStencilPath_DrawType, 1.342 + kDrawPath_DrawType, 1.343 + }; 1.344 + 1.345 + DrawType PrimTypeToDrawType(GrPrimitiveType type) { 1.346 + switch (type) { 1.347 + case kTriangles_GrPrimitiveType: 1.348 + case kTriangleStrip_GrPrimitiveType: 1.349 + case kTriangleFan_GrPrimitiveType: 1.350 + return kDrawTriangles_DrawType; 1.351 + case kPoints_GrPrimitiveType: 1.352 + return kDrawPoints_DrawType; 1.353 + case kLines_GrPrimitiveType: 1.354 + case kLineStrip_GrPrimitiveType: 1.355 + return kDrawLines_DrawType; 1.356 + default: 1.357 + GrCrash("Unexpected primitive type"); 1.358 + return kDrawTriangles_DrawType; 1.359 + } 1.360 + } 1.361 + 1.362 + // prepares clip flushes gpu state before a draw 1.363 + bool setupClipAndFlushState(DrawType, 1.364 + const GrDeviceCoordTexture* dstCopy, 1.365 + GrDrawState::AutoRestoreEffects* are, 1.366 + const SkRect* devBounds); 1.367 + 1.368 + // Functions used to map clip-respecting stencil tests into normal 1.369 + // stencil funcs supported by GPUs. 1.370 + static GrStencilFunc ConvertStencilFunc(bool stencilInClip, 1.371 + GrStencilFunc func); 1.372 + static void ConvertStencilFuncAndMask(GrStencilFunc func, 1.373 + bool clipInStencil, 1.374 + unsigned int clipBit, 1.375 + unsigned int userBits, 1.376 + unsigned int* ref, 1.377 + unsigned int* mask); 1.378 + 1.379 + GrClipMaskManager fClipMaskManager; 1.380 + 1.381 + struct GeometryPoolState { 1.382 + const GrVertexBuffer* fPoolVertexBuffer; 1.383 + int fPoolStartVertex; 1.384 + 1.385 + const GrIndexBuffer* fPoolIndexBuffer; 1.386 + int fPoolStartIndex; 1.387 + }; 1.388 + const GeometryPoolState& getGeomPoolState() { 1.389 + return fGeomPoolStateStack.back(); 1.390 + } 1.391 + 1.392 + // The state of the scissor is controlled by the clip manager 1.393 + struct ScissorState { 1.394 + bool fEnabled; 1.395 + SkIRect fRect; 1.396 + } fScissorState; 1.397 + 1.398 + // The final stencil settings to use as determined by the clip manager. 1.399 + GrStencilSettings fStencilSettings; 1.400 + 1.401 + // Helpers for setting up geometry state 1.402 + void finalizeReservedVertices(); 1.403 + void finalizeReservedIndices(); 1.404 + 1.405 +private: 1.406 + // GrDrawTarget overrides 1.407 + virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) SK_OVERRIDE; 1.408 + virtual bool onReserveIndexSpace(int indexCount, void** indices) SK_OVERRIDE; 1.409 + virtual void releaseReservedVertexSpace() SK_OVERRIDE; 1.410 + virtual void releaseReservedIndexSpace() SK_OVERRIDE; 1.411 + virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) SK_OVERRIDE; 1.412 + virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) SK_OVERRIDE; 1.413 + virtual void releaseVertexArray() SK_OVERRIDE; 1.414 + virtual void releaseIndexArray() SK_OVERRIDE; 1.415 + virtual void geometrySourceWillPush() SK_OVERRIDE; 1.416 + virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE; 1.417 + 1.418 + 1.419 + // called when the 3D context state is unknown. Subclass should emit any 1.420 + // assumed 3D context state and dirty any state cache. 1.421 + virtual void onResetContext(uint32_t resetBits) = 0; 1.422 + 1.423 + // overridden by backend-specific derived class to create objects. 1.424 + virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, 1.425 + const void* srcData, 1.426 + size_t rowBytes) = 0; 1.427 + virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) = 0; 1.428 + virtual GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) = 0; 1.429 + virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0; 1.430 + virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0; 1.431 + virtual GrPath* onCreatePath(const SkPath& path, const SkStrokeRec&) = 0; 1.432 + 1.433 + // overridden by backend-specific derived class to perform the clear and 1.434 + // clearRect. NULL rect means clear whole target. If canIgnoreRect is 1.435 + // true, it is okay to perform a full clear instead of a partial clear 1.436 + virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect) = 0; 1.437 + 1.438 + // overridden by backend-specific derived class to perform the draw call. 1.439 + virtual void onGpuDraw(const DrawInfo&) = 0; 1.440 + 1.441 + // overridden by backend-specific derived class to perform the path stenciling. 1.442 + virtual void onGpuStencilPath(const GrPath*, SkPath::FillType) = 0; 1.443 + virtual void onGpuDrawPath(const GrPath*, SkPath::FillType) = 0; 1.444 + 1.445 + // overridden by backend-specific derived class to perform flush 1.446 + virtual void onForceRenderTargetFlush() = 0; 1.447 + 1.448 + // overridden by backend-specific derived class to perform the read pixels. 1.449 + virtual bool onReadPixels(GrRenderTarget* target, 1.450 + int left, int top, int width, int height, 1.451 + GrPixelConfig, 1.452 + void* buffer, 1.453 + size_t rowBytes) = 0; 1.454 + 1.455 + // overridden by backend-specific derived class to perform the texture update 1.456 + virtual bool onWriteTexturePixels(GrTexture* texture, 1.457 + int left, int top, int width, int height, 1.458 + GrPixelConfig config, const void* buffer, 1.459 + size_t rowBytes) = 0; 1.460 + 1.461 + // overridden by backend-specific derived class to perform the resolve 1.462 + virtual void onResolveRenderTarget(GrRenderTarget* target) = 0; 1.463 + 1.464 + // width and height may be larger than rt (if underlying API allows it). 1.465 + // Should attach the SB to the RT. Returns false if compatible sb could 1.466 + // not be created. 1.467 + virtual bool createStencilBufferForRenderTarget(GrRenderTarget*, int width, int height) = 0; 1.468 + 1.469 + // attaches an existing SB to an existing RT. 1.470 + virtual bool attachStencilBufferToRenderTarget(GrStencilBuffer*, GrRenderTarget*) = 0; 1.471 + 1.472 + // The GrGpu typically records the clients requested state and then flushes 1.473 + // deltas from previous state at draw time. This function does the 1.474 + // backend-specific flush of the state. 1.475 + // returns false if current state is unsupported. 1.476 + virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) = 0; 1.477 + 1.478 + // clears the entire stencil buffer to 0 1.479 + virtual void clearStencil() = 0; 1.480 + 1.481 + // Given a rt, find or create a stencil buffer and attach it 1.482 + bool attachStencilBufferToRenderTarget(GrRenderTarget* target); 1.483 + 1.484 + // GrDrawTarget overrides 1.485 + virtual void onDraw(const DrawInfo&) SK_OVERRIDE; 1.486 + virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; 1.487 + virtual void onDrawPath(const GrPath*, SkPath::FillType, 1.488 + const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; 1.489 + 1.490 + // readies the pools to provide vertex/index data. 1.491 + void prepareVertexPool(); 1.492 + void prepareIndexPool(); 1.493 + 1.494 + void resetContext() { 1.495 + // We call this because the client may have messed with the 1.496 + // stencil buffer. Perhaps we should detect whether it is a 1.497 + // internally created stencil buffer and if so skip the invalidate. 1.498 + fClipMaskManager.invalidateStencilMask(); 1.499 + this->onResetContext(fResetBits); 1.500 + fResetBits = 0; 1.501 + ++fResetTimestamp; 1.502 + } 1.503 + 1.504 + void handleDirtyContext() { 1.505 + if (fResetBits) { 1.506 + this->resetContext(); 1.507 + } 1.508 + } 1.509 + 1.510 + enum { 1.511 + kPreallocGeomPoolStateStackCnt = 4, 1.512 + }; 1.513 + typedef SkTInternalLList<GrResource> ResourceList; 1.514 + SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true> fGeomPoolStateStack; 1.515 + ResetTimestamp fResetTimestamp; 1.516 + uint32_t fResetBits; 1.517 + GrVertexBufferAllocPool* fVertexPool; 1.518 + GrIndexBufferAllocPool* fIndexPool; 1.519 + // counts number of uses of vertex/index pool in the geometry stack 1.520 + int fVertexPoolUseCnt; 1.521 + int fIndexPoolUseCnt; 1.522 + // these are mutable so they can be created on-demand 1.523 + mutable GrIndexBuffer* fQuadIndexBuffer; 1.524 + // Used to abandon/release all resources created by this GrGpu. TODO: Move this 1.525 + // functionality to GrResourceCache. 1.526 + ResourceList fResourceList; 1.527 + 1.528 + typedef GrDrawTarget INHERITED; 1.529 +}; 1.530 + 1.531 +#endif