1 /* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef GrGpu_DEFINED 18 #define GrGpu_DEFINED 19 20 #include "GrDrawTarget.h" 21 #include "GrPathRenderer.h" 22 #include "GrRect.h" 23 #include "GrRefCnt.h" 24 #include "GrTexture.h" 25 26 class GrContext; 27 class GrIndexBufferAllocPool; 28 class GrResource; 29 class GrVertexBufferAllocPool; 30 31 /** 32 * Gpu usage statistics. 33 */ 34 struct GrGpuStats { 35 uint32_t fVertexCnt; //<! Number of vertices drawn 36 uint32_t fIndexCnt; //<! Number of indices drawn 37 uint32_t fDrawCnt; //<! Number of draws 38 39 uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed) 40 41 /* 42 * Number of times the texture is set in 3D API 43 */ 44 uint32_t fTextureChngCnt; 45 /* 46 * Number of times the render target is set in 3D API 47 */ 48 uint32_t fRenderTargetChngCnt; 49 /* 50 * Number of textures created (includes textures that are rendertargets). 51 */ 52 uint32_t fTextureCreateCnt; 53 /* 54 * Number of rendertargets created. 55 */ 56 uint32_t fRenderTargetCreateCnt; 57 }; 58 59 class GrGpu : public GrDrawTarget { 60 61 public: 62 /** 63 * Additional blend coeffecients for dual source blending, not exposed 64 * through GrPaint/GrContext. 65 */ 66 enum ExtendedBlendCoeffs { 67 // source 2 refers to second output color when 68 // using dual source blending. 69 kS2C_BlendCoeff = kPublicBlendCoeffCount, 70 kIS2C_BlendCoeff, 71 kS2A_BlendCoeff, 72 kIS2A_BlendCoeff, 73 74 kTotalBlendCoeffCount 75 }; 76 77 /** 78 * Create an instance of GrGpu that matches the specified Engine backend. 79 * If the requested engine is not supported (at compile-time or run-time) 80 * this returns NULL. 81 */ 82 static GrGpu* Create(GrEngine, GrPlatform3DContext context3D); 83 84 //////////////////////////////////////////////////////////////////////////// 85 86 GrGpu(); 87 virtual ~GrGpu(); 88 89 // The GrContext sets itself as the owner of this Gpu object setContext(GrContext * context)90 void setContext(GrContext* context) { 91 GrAssert(NULL == fContext); 92 fContext = context; 93 } getContext()94 GrContext* getContext() { return fContext; } getContext()95 const GrContext* getContext() const { return fContext; } 96 97 /** 98 * The GrGpu object normally assumes that no outsider is setting state 99 * within the underlying 3D API's context/device/whatever. This call informs 100 * the GrGpu that the state was modified and it shouldn't make assumptions 101 * about the state. 102 */ markContextDirty()103 void markContextDirty() { fContextIsDirty = true; } 104 105 void unimpl(const char[]); 106 107 /** 108 * Creates a texture object. If desc width or height is not a power of 109 * two but underlying API requires a power of two texture then srcData 110 * will be embedded in a power of two texture. The extra width and height 111 * is filled as though srcData were rendered clamped into the texture. 112 * 113 * If kRenderTarget_TextureFlag is specified the GrRenderTarget is 114 * accessible via GrTexture::asRenderTarget(). The texture will hold a ref 115 * on the render target until its releaseRenderTarget() is called or it is 116 * destroyed. 117 * 118 * @param desc describes the texture to be created. 119 * @param srcData texel data to load texture. Begins with full-size 120 * palette data for paletted textures. Contains width* 121 * height texels. If NULL texture data is uninitialized. 122 * 123 * @return The texture object if successful, otherwise NULL. 124 */ 125 GrTexture* createTexture(const GrTextureDesc& desc, 126 const void* srcData, size_t rowBytes); 127 128 GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc); 129 130 /** 131 * Reads the current target object (e.g. FBO or IDirect3DSurface9*) and 132 * viewport state from the underlying 3D API and wraps it in a 133 * GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the 134 * underlying object in its destructor and it is up to caller to guarantee 135 * that it remains valid while the GrRenderTarget is used. 136 * 137 * @return the newly created GrRenderTarget 138 */ 139 GrRenderTarget* createRenderTargetFrom3DApiState(); 140 141 /** 142 * Creates a vertex buffer. 143 * 144 * @param size size in bytes of the vertex buffer 145 * @param dynamic hints whether the data will be frequently changed 146 * by either GrVertexBuffer::lock or 147 * GrVertexBuffer::updateData. 148 * 149 * @return The vertex buffer if successful, otherwise NULL. 150 */ 151 GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic); 152 153 /** 154 * Creates an index buffer. 155 * 156 * @param size size in bytes of the index buffer 157 * @param dynamic hints whether the data will be frequently changed 158 * by either GrIndexBuffer::lock or 159 * GrIndexBuffer::updateData. 160 * 161 * @return The index buffer if successful, otherwise NULL. 162 */ 163 GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic); 164 165 /** 166 * Are 8 bit paletted textures supported. 167 * 168 * @return true if 8bit palette textures are supported, false otherwise 169 */ supports8BitPalette()170 bool supports8BitPalette() const { return f8bitPaletteSupport; } 171 172 /** 173 * returns true if two sided stenciling is supported. If false then only 174 * the front face values of the GrStencilSettings 175 * @return true if only a single stencil pass is needed. 176 */ supportsTwoSidedStencil()177 bool supportsTwoSidedStencil() const 178 { return fTwoSidedStencilSupport; } 179 180 /** 181 * returns true if stencil wrap is supported. If false then 182 * kIncWrap_StencilOp and kDecWrap_StencilOp are treated as 183 * kIncClamp_StencilOp and kDecClamp_StencilOp, respectively. 184 * @return true if stencil wrap ops are supported. 185 */ supportsStencilWrapOps()186 bool supportsStencilWrapOps() const 187 { return fStencilWrapOpsSupport; } 188 189 /** 190 * Checks whether locking vertex and index buffers is supported. 191 * 192 * @return true if locking is supported. 193 */ supportsBufferLocking()194 bool supportsBufferLocking() const { return fBufferLockSupport; } 195 196 /** 197 * Does the 3D API support anti-aliased lines. If so then line primitive 198 * types will use this functionality when the AA state flag is set. 199 */ supportsAALines()200 bool supportsAALines() const { return fAALineSupport; } 201 202 /** 203 * Does the subclass support GrSamplerState::k4x4Downsample_Filter 204 */ supports4x4DownsampleFilter()205 bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; } 206 207 /** 208 * Does this instance support dual-source blending? Required for proper 209 * blending with partial coverage with certain blend modes (dst coeff is 210 * not 1, ISA, or ISC) 211 */ supportsDualSourceBlending()212 bool supportsDualSourceBlending() const { 213 return fDualSourceBlendingSupport; 214 } 215 216 /** 217 * Gets the minimum width of a render target. If a texture/rt is created 218 * with a width less than this size the GrGpu object will clamp it to this 219 * value. 220 */ minRenderTargetWidth()221 int minRenderTargetWidth() const { return fMinRenderTargetWidth; } 222 223 /** 224 * Gets the minimum width of a render target. If a texture/rt is created 225 * with a height less than this size the GrGpu object will clamp it to this 226 * value. 227 */ minRenderTargetHeight()228 int minRenderTargetHeight() const { return fMinRenderTargetHeight; } 229 230 /** 231 * Reports whether full scene anti-aliasing is supported. 232 */ supportsFullsceneAA()233 bool supportsFullsceneAA() const { return fFSAASupport; } 234 235 /** 236 * Returns true if NPOT textures can be created 237 * 238 * @return true if NPOT textures can be created 239 */ npotTextureSupport()240 bool npotTextureSupport() const { return fNPOTTextureSupport; } 241 242 /** 243 * Returns true if NPOT textures can be repeat/mirror tiled. 244 * 245 * @return true if NPOT textures can be tiled 246 */ npotTextureTileSupport()247 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 248 249 /** 250 * Returns true if a NPOT texture can be a rendertarget 251 * 252 * @return the true if NPOT texture/rendertarget can be created. 253 */ npotRenderTargetSupport()254 bool npotRenderTargetSupport() const { return fNPOTRenderTargetSupport; } 255 maxTextureDimension()256 int maxTextureDimension() const { return fMaxTextureDimension; } 257 258 // GrDrawTarget overrides 259 virtual void drawIndexed(GrPrimitiveType type, 260 int startVertex, 261 int startIndex, 262 int vertexCount, 263 int indexCount); 264 265 virtual void drawNonIndexed(GrPrimitiveType type, 266 int startVertex, 267 int vertexCount); 268 virtual void clear(const GrIRect* rect, GrColor color); 269 270 /** 271 * Installs a path renderer that will be used to draw paths that are 272 * part of the clip. 273 */ setClipPathRenderer(GrPathRenderer * pathRenderer)274 void setClipPathRenderer(GrPathRenderer* pathRenderer) { 275 GrSafeAssign(fClientPathRenderer, pathRenderer); 276 } 277 278 /** 279 * Returns an index buffer that can be used to render quads. 280 * Six indices per quad: 0, 1, 2, 0, 2, 3, etc. 281 * The max number of quads can be queried using GrIndexBuffer::maxQuads(). 282 * Draw with kTriangles_PrimitiveType 283 * @ return the quad index buffer 284 */ 285 const GrIndexBuffer* getQuadIndexBuffer() const; 286 287 /** 288 * Returns a vertex buffer with four position-only vertices [(0,0), (1,0), 289 * (1,1), (0,1)]. 290 * @ return unit square vertex buffer 291 */ 292 const GrVertexBuffer* getUnitSquareVertexBuffer() const; 293 294 /** 295 * Ensures that the current render target is actually set in the 296 * underlying 3D API. Used when client wants to use 3D API to directly 297 * render to the RT. 298 */ 299 void forceRenderTargetFlush(); 300 301 /** 302 * Reads a rectangle of pixels from a render target. 303 * @param renderTarget the render target to read from. NULL means the 304 * current render target. 305 * @param left left edge of the rectangle to read (inclusive) 306 * @param top top edge of the rectangle to read (inclusive) 307 * @param width width of rectangle to read in pixels. 308 * @param height height of rectangle to read in pixels. 309 * @param config the pixel config of the destination buffer 310 * @param buffer memory to read the rectangle into. 311 * 312 * @return true if the read succeeded, false if not. The read can fail 313 * because of a unsupported pixel config or because no render 314 * target is currently set. 315 */ 316 bool readPixels(GrRenderTarget* renderTarget, 317 int left, int top, int width, int height, 318 GrPixelConfig config, void* buffer); 319 320 const GrGpuStats& getStats() const; 321 void resetStats(); 322 void printStats() const; 323 324 /** 325 * Called to tell Gpu object that all GrResources have been lost and should 326 * be abandoned. 327 */ 328 virtual void abandonResources(); 329 330 /** 331 * Called to tell Gpu object to release all GrResources. 332 */ 333 void releaseResources(); 334 335 /** 336 * Add resource to list of resources. Should only be called by GrResource. 337 * @param resource the resource to add. 338 */ 339 void insertResource(GrResource* resource); 340 341 /** 342 * Remove resource from list of resources. Should only be called by 343 * GrResource. 344 * @param resource the resource to remove. 345 */ 346 void removeResource(GrResource* resource); 347 348 protected: 349 enum PrivateStateBits { 350 kFirstBit = (kLastPublicStateBit << 1), 351 352 kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify 353 // stencil bits used for 354 // clipping. 355 }; 356 357 /** 358 * Extensions to GrDrawTarget::StateBits to implement stencil clipping 359 */ 360 struct ClipState { 361 bool fClipInStencil; 362 bool fClipIsDirty; 363 } fClipState; 364 365 // GrDrawTarget override 366 virtual void clipWillBeSet(const GrClip& newClip); 367 368 // prepares clip flushes gpu state before a draw 369 bool setupClipAndFlushState(GrPrimitiveType type); 370 371 // Functions used to map clip-respecting stencil tests into normal 372 // stencil funcs supported by GPUs. 373 static GrStencilFunc ConvertStencilFunc(bool stencilInClip, 374 GrStencilFunc func); 375 static void ConvertStencilFuncAndMask(GrStencilFunc func, 376 bool clipInStencil, 377 unsigned int clipBit, 378 unsigned int userBits, 379 unsigned int* ref, 380 unsigned int* mask); 381 382 // stencil settings to clip drawing when stencil clipping is in effect 383 // and the client isn't using the stencil test. 384 static const GrStencilSettings gClipStencilSettings; 385 386 // defaults to false, subclass can set true to support palleted textures 387 bool f8bitPaletteSupport; 388 389 // set by subclass 390 bool fNPOTTextureSupport; 391 bool fNPOTTextureTileSupport; 392 bool fNPOTRenderTargetSupport; 393 bool fTwoSidedStencilSupport; 394 bool fStencilWrapOpsSupport; 395 bool fAALineSupport; 396 bool fFSAASupport; 397 bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter 398 bool fDualSourceBlendingSupport; 399 400 // set by subclass to true if index and vertex buffers can be locked, false 401 // otherwise. 402 bool fBufferLockSupport; 403 404 // set by subclass 405 int fMinRenderTargetWidth; 406 int fMinRenderTargetHeight; 407 int fMaxTextureDimension; 408 409 GrGpuStats fStats; 410 411 const GrVertexBuffer* fCurrPoolVertexBuffer; 412 int fCurrPoolStartVertex; 413 414 const GrIndexBuffer* fCurrPoolIndexBuffer; 415 int fCurrPoolStartIndex; 416 417 // GrDrawTarget overrides 418 virtual bool onAcquireGeometry(GrVertexLayout vertexLayout, 419 void** vertices, 420 void** indices); 421 virtual void onReleaseGeometry(); 422 423 virtual void onSetVertexSourceToArray(const void* vertexArray, 424 int vertexCount); 425 426 virtual void onSetIndexSourceToArray(const void* indexArray, 427 int indexCount); 428 // Helpers for setting up geometry state 429 void finalizeReservedVertices(); 430 void finalizeReservedIndices(); 431 432 // overridden by API-specific derived class to handle re-emitting 3D API 433 // preample and dirtying state cache. 434 virtual void resetContext() = 0; 435 436 // overridden by API-specific derived class to create objects. 437 virtual GrTexture* onCreateTexture(const GrTextureDesc& desc, 438 const void* srcData, 439 size_t rowBytes) = 0; 440 virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0; 441 virtual GrRenderTarget* onCreateRenderTargetFrom3DApiState() = 0; 442 virtual GrVertexBuffer* onCreateVertexBuffer(uint32_t size, 443 bool dynamic) = 0; 444 virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, 445 bool dynamic) = 0; 446 447 // overridden by API-specific derivated class to perform the clear and 448 // clearRect. NULL rect means clear whole target. 449 virtual void onClear(const GrIRect* rect, GrColor color) = 0; 450 451 // overridden by API-specific derived class to perform the draw call. 452 virtual void onDrawIndexed(GrPrimitiveType type, 453 uint32_t startVertex, 454 uint32_t startIndex, 455 uint32_t vertexCount, 456 uint32_t indexCount) = 0; 457 458 virtual void onDrawNonIndexed(GrPrimitiveType type, 459 uint32_t vertexCount, 460 uint32_t numVertices) = 0; 461 462 // overridden by API-specific derived class to perform flush 463 virtual void onForceRenderTargetFlush() = 0; 464 465 // overridden by API-specific derived class to perform the read pixels. 466 virtual bool onReadPixels(GrRenderTarget* target, 467 int left, int top, int width, int height, 468 GrPixelConfig, void* buffer) = 0; 469 470 // called to program the vertex data, indexCount will be 0 if drawing non- 471 // indexed geometry. The subclass may adjust the startVertex and/or 472 // startIndex since it may have already accounted for these in the setup. 473 virtual void setupGeometry(int* startVertex, 474 int* startIndex, 475 int vertexCount, 476 int indexCount) = 0; 477 478 479 // The GrGpu typically records the clients requested state and then flushes 480 // deltas from previous state at draw time. This function does the 481 // API-specific flush of the state 482 // returns false if current state is unsupported. 483 virtual bool flushGraphicsState(GrPrimitiveType type) = 0; 484 485 // Sets the scissor rect, or disables if rect is NULL. 486 virtual void flushScissor(const GrIRect* rect) = 0; 487 488 // GrGpu subclass removes the clip from the stencil buffer 489 virtual void clearStencilClip(const GrIRect& rect) = 0; 490 491 private: 492 GrContext* fContext; // not reffed (context refs gpu) 493 494 GrVertexBufferAllocPool* fVertexPool; 495 496 GrIndexBufferAllocPool* fIndexPool; 497 498 mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be 499 // created on-demand 500 501 mutable GrVertexBuffer* fUnitSquareVertexBuffer; // mutable so it can be 502 // created on-demand 503 504 GrDefaultPathRenderer* fDefaultPathRenderer; 505 GrPathRenderer* fClientPathRenderer; 506 507 bool fContextIsDirty; 508 509 // when in an internal draw these indicate whether the pools are in use 510 // by one of the outer draws. If false then it is safe to reset the 511 // pool. 512 bool fVertexPoolInUse; 513 bool fIndexPoolInUse; 514 515 GrResource* fResourceHead; 516 517 // readies the pools to provide vertex/index data. 518 void prepareVertexPool(); 519 void prepareIndexPool(); 520 521 // determines the path renderer used to draw a clip path element. 522 GrPathRenderer* getClipPathRenderer(const SkPath& path, GrPathFill fill); 523 handleDirtyContext()524 void handleDirtyContext() { 525 if (fContextIsDirty) { 526 this->resetContext(); 527 fContextIsDirty = false; 528 } 529 } 530 531 // used to save and restore state when the GrGpu needs 532 // to make its geometry pools available internally 533 class AutoInternalDrawGeomRestore { 534 public: AutoInternalDrawGeomRestore(GrGpu * gpu)535 AutoInternalDrawGeomRestore(GrGpu* gpu) : fAgsr(gpu) { 536 fGpu = gpu; 537 538 fVertexPoolWasInUse = gpu->fVertexPoolInUse; 539 fIndexPoolWasInUse = gpu->fIndexPoolInUse; 540 541 gpu->fVertexPoolInUse = fVertexPoolWasInUse || 542 (kBuffer_GeometrySrcType != 543 gpu->fGeometrySrc.fVertexSrc); 544 gpu->fIndexPoolInUse = fIndexPoolWasInUse || 545 (kBuffer_GeometrySrcType != 546 gpu->fGeometrySrc.fIndexSrc);; 547 548 fSavedPoolVertexBuffer = gpu->fCurrPoolVertexBuffer; 549 fSavedPoolStartVertex = gpu->fCurrPoolStartVertex; 550 fSavedPoolIndexBuffer = gpu->fCurrPoolIndexBuffer; 551 fSavedPoolStartIndex = gpu->fCurrPoolStartIndex; 552 553 fSavedReservedGeometry = gpu->fReservedGeometry; 554 gpu->fReservedGeometry.fLocked = false; 555 } ~AutoInternalDrawGeomRestore()556 ~AutoInternalDrawGeomRestore() { 557 fGpu->fCurrPoolVertexBuffer = fSavedPoolVertexBuffer; 558 fGpu->fCurrPoolStartVertex = fSavedPoolStartVertex; 559 fGpu->fCurrPoolIndexBuffer = fSavedPoolIndexBuffer; 560 fGpu->fCurrPoolStartIndex = fSavedPoolStartIndex; 561 fGpu->fVertexPoolInUse = fVertexPoolWasInUse; 562 fGpu->fIndexPoolInUse = fIndexPoolWasInUse; 563 fGpu->fReservedGeometry = fSavedReservedGeometry; 564 } 565 private: 566 AutoGeometrySrcRestore fAgsr; 567 GrGpu* fGpu; 568 const GrVertexBuffer* fSavedPoolVertexBuffer; 569 int fSavedPoolStartVertex; 570 const GrIndexBuffer* fSavedPoolIndexBuffer; 571 int fSavedPoolStartIndex; 572 bool fVertexPoolWasInUse; 573 bool fIndexPoolWasInUse; 574 ReservedGeometry fSavedReservedGeometry; 575 }; 576 577 typedef GrDrawTarget INHERITED; 578 }; 579 580 #endif 581