1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrGLGpu_DEFINED 9 #define GrGLGpu_DEFINED 10 11 #include "GrGLContext.h" 12 #include "GrGLIRect.h" 13 #include "GrGLIndexBuffer.h" 14 #include "GrGLPathRendering.h" 15 #include "GrGLProgram.h" 16 #include "GrGLRenderTarget.h" 17 #include "GrGLStencilAttachment.h" 18 #include "GrGLTexture.h" 19 #include "GrGLTransferBuffer.h" 20 #include "GrGLVertexArray.h" 21 #include "GrGLVertexBuffer.h" 22 #include "GrGpu.h" 23 #include "GrPipelineBuilder.h" 24 #include "GrXferProcessor.h" 25 #include "SkTypes.h" 26 27 class GrPipeline; 28 class GrNonInstancedVertices; 29 class GrSwizzle; 30 31 #ifdef SK_DEVELOPER 32 #define PROGRAM_CACHE_STATS 33 #endif 34 35 class GrGLGpu : public GrGpu { 36 public: 37 static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options, 38 GrContext* context); 39 ~GrGLGpu() override; 40 41 void contextAbandoned() override; 42 43 const GrGLContext& glContext() const { return *fGLContext; } 44 45 const GrGLInterface* glInterface() const { return fGLContext->interface(); } 46 const GrGLContextInfo& ctxInfo() const { return *fGLContext; } 47 GrGLStandard glStandard() const { return fGLContext->standard(); } 48 GrGLVersion glVersion() const { return fGLContext->version(); } 49 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } 50 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 51 52 GrGLPathRendering* glPathRendering() { 53 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 54 return static_cast<GrGLPathRendering*>(pathRendering()); 55 } 56 57 void discard(GrRenderTarget*) override; 58 59 // Used by GrGLProgram to configure OpenGL state. 60 void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture); 61 62 bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes, 63 GrPixelConfig readConfig, DrawPreference*, 64 ReadPixelTempDrawInfo*) override; 65 66 bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 67 GrPixelConfig srcConfig, DrawPreference*, 68 WritePixelTempDrawInfo*) override; 69 70 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) const override; 71 72 // These functions should be used to bind GL objects. They track the GL state and skip redundant 73 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. 74 void bindVertexArray(GrGLuint id) { 75 fHWGeometryState.setVertexArrayID(this, id); 76 } 77 void bindIndexBufferAndDefaultVertexArray(GrGLuint id) { 78 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, id); 79 } 80 void bindVertexBuffer(GrGLuint id) { 81 fHWGeometryState.setVertexBufferID(this, id); 82 } 83 84 // These callbacks update state tracking when GL objects are deleted. They are called from 85 // GrGLResource onRelease functions. 86 void notifyVertexArrayDelete(GrGLuint id) { 87 fHWGeometryState.notifyVertexArrayDelete(id); 88 } 89 void notifyVertexBufferDelete(GrGLuint id) { 90 fHWGeometryState.notifyVertexBufferDelete(id); 91 } 92 void notifyIndexBufferDelete(GrGLuint id) { 93 fHWGeometryState.notifyIndexBufferDelete(id); 94 } 95 96 void buildProgramDesc(GrProgramDesc*, 97 const GrPrimitiveProcessor&, 98 const GrPipeline&) const override; 99 100 // id and type (GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER) of buffer to bind 101 void bindBuffer(GrGLuint id, GrGLenum type); 102 103 void releaseBuffer(GrGLuint id, GrGLenum type); 104 105 // sizes are in bytes 106 void* mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize, 107 size_t requestedSize); 108 109 void unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr); 110 111 void bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize, 112 const void* src, size_t srcSizeInBytes); 113 114 const GrGLContext* glContextForTesting() const override { 115 return &this->glContext(); 116 } 117 118 void clearStencil(GrRenderTarget*) override; 119 120 void invalidateBoundRenderTarget() { 121 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; 122 } 123 124 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 125 int width, 126 int height) override; 127 128 GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h, 129 GrPixelConfig config) override; 130 bool isTestingOnlyBackendTexture(GrBackendObject) const override; 131 void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override; 132 133 void resetShaderCacheForTesting() const override; 134 135 void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override; 136 137 void finishDrawTarget() override; 138 139 private: 140 GrGLGpu(GrGLContext* ctx, GrContext* context); 141 142 // GrGpu overrides 143 void onResetContext(uint32_t resetBits) override; 144 145 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 146 147 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, 148 const void* srcData, size_t rowBytes) override; 149 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, 150 GrGpuResource::LifeCycle lifeCycle, 151 const void* srcData) override; 152 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override; 153 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override; 154 GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) override; 155 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override; 156 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&, 157 GrWrapOwnership) override; 158 GrRenderTarget* onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&, 159 GrWrapOwnership) override; 160 // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a 161 // compatible stencil format, or negative if there is no compatible stencil format. 162 int getCompatibleStencilIndex(GrPixelConfig config); 163 164 // If |desc.fTextureStorageAllocator| exists, use that to create the 165 // texture. Otherwise, create the texture directly. 166 // Returns whether the texture is successfully created. On success, the 167 // result is stored in |info|. 168 // The texture is populated with |srcData|, if it exists. 169 // The texture parameters are cached in |initialTexParams|. 170 bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, 171 bool renderTarget, const void* srcData, 172 GrGLTexture::TexParams* initialTexParams, size_t rowBytes); 173 bool createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, 174 const void* srcData, size_t rowBytes); 175 176 void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override; 177 178 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override; 179 180 bool onMakeCopyForTextureParams(GrTexture*, const GrTextureParams&, 181 GrTextureProducer::CopyParams*) const override; 182 183 // Checks whether glReadPixels can be called to get pixel values in readConfig from the 184 // render target. 185 bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig); 186 187 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 188 // render target that has renderTargetConfig. This may have to create a temporary 189 // render target and thus is less preferable than the variant that takes a render target. 190 bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig); 191 192 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 193 // render target that has the same config as surfaceForConfig. Calls one of the the two 194 // variations above, depending on whether the surface is a render target or not. 195 bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig); 196 197 bool onReadPixels(GrSurface*, 198 int left, int top, 199 int width, int height, 200 GrPixelConfig, 201 void* buffer, 202 size_t rowBytes) override; 203 204 bool onWritePixels(GrSurface*, 205 int left, int top, int width, int height, 206 GrPixelConfig config, const void* buffer, 207 size_t rowBytes) override; 208 209 bool onTransferPixels(GrSurface*, 210 int left, int top, int width, int height, 211 GrPixelConfig config, GrTransferBuffer* buffer, 212 size_t offset, size_t rowBytes) override; 213 214 void onResolveRenderTarget(GrRenderTarget* target) override; 215 216 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override; 217 218 bool onCopySurface(GrSurface* dst, 219 GrSurface* src, 220 const SkIRect& srcRect, 221 const SkIPoint& dstPoint) override; 222 223 // binds texture unit in GL 224 void setTextureUnit(int unitIdx); 225 226 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. 227 bool flushGLState(const DrawArgs&); 228 229 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset 230 // an into the index buffer. It does not account for vertices.startIndex() but rather the start 231 // index is relative to the returned offset. 232 void setupGeometry(const GrPrimitiveProcessor&, 233 const GrNonInstancedVertices& vertices, 234 size_t* indexOffsetInBytes); 235 236 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 237 238 bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); } 239 240 void copySurfaceAsDraw(GrSurface* dst, 241 GrSurface* src, 242 const SkIRect& srcRect, 243 const SkIPoint& dstPoint); 244 void copySurfaceAsCopyTexSubImage(GrSurface* dst, 245 GrSurface* src, 246 const SkIRect& srcRect, 247 const SkIPoint& dstPoint); 248 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, 249 GrSurface* src, 250 const SkIRect& srcRect, 251 const SkIPoint& dstPoint); 252 253 void stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform, 254 GrGLuint arrayBuffer); 255 256 void setupPixelLocalStorage(const DrawArgs& args); 257 258 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 259 260 class ProgramCache : public ::SkNoncopyable { 261 public: 262 ProgramCache(GrGLGpu* gpu); 263 ~ProgramCache(); 264 265 void reset(); 266 void abandon(); 267 GrGLProgram* refProgram(const DrawArgs&); 268 269 private: 270 enum { 271 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 272 // shader before evicting from the cache. 273 kMaxEntries = 128, 274 kHashBits = 6, 275 }; 276 277 struct Entry; 278 279 struct ProgDescLess; 280 281 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 282 // of the index of where it should be inserted. 283 int search(const GrProgramDesc& desc) const; 284 285 // sorted array of all the entries 286 Entry* fEntries[kMaxEntries]; 287 // hash table based on lowest kHashBits bits of the program key. Used to avoid binary 288 // searching fEntries. 289 Entry* fHashTable[1 << kHashBits]; 290 291 int fCount; 292 unsigned int fCurrLRUStamp; 293 GrGLGpu* fGpu; 294 #ifdef PROGRAM_CACHE_STATS 295 int fTotalRequests; 296 int fCacheMisses; 297 int fHashMisses; // cache hit but hash table missed 298 #endif 299 }; 300 301 void flushColorWrite(bool writeColor); 302 void flushDrawFace(GrPipelineBuilder::DrawFace face); 303 304 // flushes the scissor. see the note on flushBoundTextureAndParams about 305 // flushing the scissor after that function is called. 306 void flushScissor(const GrScissorState&, 307 const GrGLIRect& rtViewport, 308 GrSurfaceOrigin rtOrigin); 309 310 // disables the scissor 311 void disableScissor(); 312 313 void initFSAASupport(); 314 315 // determines valid stencil formats 316 void initStencilFormats(); 317 318 // sets a texture unit to use for texture operations other than binding a texture to a program. 319 // ensures that such operations don't negatively interact with tracking bound textures. 320 void setScratchTextureUnit(); 321 322 // bounds is region that may be modified. 323 // nullptr means whole target. Can be an empty rect. 324 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds); 325 // Handles cases where a surface will be updated without a call to flushRenderTarget 326 void didWriteToSurface(GrSurface*, const SkIRect* bounds) const; 327 328 // Need not be called if flushRenderTarget is used. 329 void flushViewport(const GrGLIRect&); 330 331 void flushStencil(const GrStencilSettings&); 332 333 // rt is used only if useHWAA is true. 334 void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled); 335 336 // helper for onCreateTexture and writeTexturePixels 337 enum UploadType { 338 kNewTexture_UploadType, // we are creating a new texture 339 kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture 340 kTransfer_UploadType, // we are using a transfer buffer to copy data 341 }; 342 bool uploadTexData(const GrSurfaceDesc& desc, 343 GrGLenum target, 344 UploadType uploadType, 345 int left, int top, int width, int height, 346 GrPixelConfig dataConfig, 347 const void* data, 348 size_t rowBytes); 349 350 // helper for onCreateCompressedTexture. If width and height are 351 // set to -1, then this function will use desc.fWidth and desc.fHeight 352 // for the size of the data. The isNewTexture flag should be set to true 353 // whenever a new texture needs to be created. Otherwise, we assume that 354 // the texture is already in GPU memory and that it's going to be updated 355 // with new data. 356 bool uploadCompressedTexData(const GrSurfaceDesc& desc, 357 GrGLenum target, 358 const void* data, 359 UploadType uploadType = kNewTexture_UploadType, 360 int left = 0, int top = 0, 361 int width = -1, int height = -1); 362 363 bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle, 364 const GrGLTextureInfo& texInfo, GrGLRenderTarget::IDDesc*); 365 366 enum TempFBOTarget { 367 kSrc_TempFBOTarget, 368 kDst_TempFBOTarget 369 }; 370 371 // Binds a surface as a FBO for a copy operation. If the surface already owns an FBO ID then 372 // that ID is bound. If not the surface is temporarily bound to a FBO and that FBO is bound. 373 // This must be paired with a call to unbindSurfaceFBOForCopy(). 374 void bindSurfaceFBOForCopy(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 375 TempFBOTarget tempFBOTarget); 376 377 // Must be called if bindSurfaceFBOForCopy was used to bind a surface for copying. 378 void unbindTextureFBOForCopy(GrGLenum fboTarget, GrSurface* surface); 379 380 SkAutoTUnref<GrGLContext> fGLContext; 381 382 void createCopyPrograms(); 383 void createWireRectProgram(); 384 void createUnitRectBuffer(); 385 386 void createPLSSetupProgram(); 387 388 // GL program-related state 389 ProgramCache* fProgramCache; 390 391 /////////////////////////////////////////////////////////////////////////// 392 ///@name Caching of GL State 393 ///@{ 394 int fHWActiveTextureUnitIdx; 395 GrGLuint fHWProgramID; 396 397 enum TriState { 398 kNo_TriState, 399 kYes_TriState, 400 kUnknown_TriState 401 }; 402 403 GrGLuint fTempSrcFBOID; 404 GrGLuint fTempDstFBOID; 405 406 GrGLuint fStencilClearFBOID; 407 408 // last scissor / viewport scissor state seen by the GL. 409 struct { 410 TriState fEnabled; 411 GrGLIRect fRect; 412 void invalidate() { 413 fEnabled = kUnknown_TriState; 414 fRect.invalidate(); 415 } 416 } fHWScissorSettings; 417 418 GrGLIRect fHWViewport; 419 420 /** 421 * Tracks bound vertex and index buffers and vertex attrib array state. 422 */ 423 class HWGeometryState { 424 public: 425 HWGeometryState() { fVBOVertexArray = nullptr; this->invalidate(); } 426 427 ~HWGeometryState() { delete fVBOVertexArray; } 428 429 void invalidate() { 430 fBoundVertexArrayIDIsValid = false; 431 fBoundVertexBufferIDIsValid = false; 432 fDefaultVertexArrayBoundIndexBufferID = false; 433 fDefaultVertexArrayBoundIndexBufferIDIsValid = false; 434 fDefaultVertexArrayAttribState.invalidate(); 435 if (fVBOVertexArray) { 436 fVBOVertexArray->invalidateCachedState(); 437 } 438 } 439 440 void notifyVertexArrayDelete(GrGLuint id) { 441 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 442 // Does implicit bind to 0 443 fBoundVertexArrayID = 0; 444 } 445 } 446 447 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 448 if (!gpu->glCaps().vertexArrayObjectSupport()) { 449 SkASSERT(0 == arrayID); 450 return; 451 } 452 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 453 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 454 fBoundVertexArrayIDIsValid = true; 455 fBoundVertexArrayID = arrayID; 456 } 457 } 458 459 void notifyVertexBufferDelete(GrGLuint id) { 460 if (fBoundVertexBufferIDIsValid && id == fBoundVertexBufferID) { 461 fBoundVertexBufferID = 0; 462 } 463 if (fVBOVertexArray) { 464 fVBOVertexArray->notifyVertexBufferDelete(id); 465 } 466 fDefaultVertexArrayAttribState.notifyVertexBufferDelete(id); 467 } 468 469 void notifyIndexBufferDelete(GrGLuint id) { 470 if (fDefaultVertexArrayBoundIndexBufferIDIsValid && 471 id == fDefaultVertexArrayBoundIndexBufferID) { 472 fDefaultVertexArrayBoundIndexBufferID = 0; 473 } 474 if (fVBOVertexArray) { 475 fVBOVertexArray->notifyIndexBufferDelete(id); 476 } 477 } 478 479 void setVertexBufferID(GrGLGpu* gpu, GrGLuint id) { 480 if (!fBoundVertexBufferIDIsValid || id != fBoundVertexBufferID) { 481 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ARRAY_BUFFER, id)); 482 fBoundVertexBufferIDIsValid = true; 483 fBoundVertexBufferID = id; 484 } 485 } 486 487 /** 488 * Binds the default vertex array and binds the index buffer. This is used when binding 489 * an index buffer in order to update it. 490 */ 491 void setIndexBufferIDOnDefaultVertexArray(GrGLGpu* gpu, GrGLuint id) { 492 this->setVertexArrayID(gpu, 0); 493 if (!fDefaultVertexArrayBoundIndexBufferIDIsValid || 494 id != fDefaultVertexArrayBoundIndexBufferID) { 495 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, id)); 496 fDefaultVertexArrayBoundIndexBufferIDIsValid = true; 497 fDefaultVertexArrayBoundIndexBufferID = id; 498 } 499 } 500 501 /** 502 * Binds the vertex array object that should be used to render from the vertex buffer. 503 * The vertex array is bound and its attrib array state object is returned. The vertex 504 * buffer is bound. The index buffer (if non-nullptr) is bound to the vertex array. The 505 * returned GrGLAttribArrayState should be used to set vertex attribute arrays. 506 */ 507 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu, 508 const GrGLVertexBuffer* vbuffer, 509 const GrGLIndexBuffer* ibuffer); 510 511 /** Variants of the above that takes GL buffer IDs. Note that 0 does not imply that a 512 buffer won't be bound. The "default buffer" will be bound, which is used for client-side 513 array rendering. */ 514 GrGLAttribArrayState* bindArrayAndBufferToDraw(GrGLGpu* gpu, GrGLuint vbufferID); 515 GrGLAttribArrayState* bindArrayAndBuffersToDraw(GrGLGpu* gpu, 516 GrGLuint vbufferID, 517 GrGLuint ibufferID); 518 519 private: 520 GrGLAttribArrayState* internalBind(GrGLGpu* gpu, GrGLuint vbufferID, GrGLuint* ibufferID); 521 522 GrGLuint fBoundVertexArrayID; 523 GrGLuint fBoundVertexBufferID; 524 bool fBoundVertexArrayIDIsValid; 525 bool fBoundVertexBufferIDIsValid; 526 527 GrGLuint fDefaultVertexArrayBoundIndexBufferID; 528 bool fDefaultVertexArrayBoundIndexBufferIDIsValid; 529 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 530 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 531 // GrGLGpu. 532 GrGLAttribArrayState fDefaultVertexArrayAttribState; 533 534 // This is used when we're using a core profile and the vertices are in a VBO. 535 GrGLVertexArray* fVBOVertexArray; 536 } fHWGeometryState; 537 538 struct { 539 GrBlendEquation fEquation; 540 GrBlendCoeff fSrcCoeff; 541 GrBlendCoeff fDstCoeff; 542 GrColor fConstColor; 543 bool fConstColorValid; 544 TriState fEnabled; 545 546 void invalidate() { 547 fEquation = static_cast<GrBlendEquation>(-1); 548 fSrcCoeff = static_cast<GrBlendCoeff>(-1); 549 fDstCoeff = static_cast<GrBlendCoeff>(-1); 550 fConstColorValid = false; 551 fEnabled = kUnknown_TriState; 552 } 553 } fHWBlendState; 554 555 TriState fMSAAEnabled; 556 557 GrStencilSettings fHWStencilSettings; 558 TriState fHWStencilTestEnabled; 559 560 561 GrPipelineBuilder::DrawFace fHWDrawFace; 562 TriState fHWWriteToColor; 563 uint32_t fHWBoundRenderTargetUniqueID; 564 TriState fHWSRGBFramebuffer; 565 SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs; 566 567 // EXT_raster_multisample. 568 TriState fHWRasterMultisampleEnabled; 569 int fHWNumRasterSamples; 570 ///@} 571 572 /** IDs for copy surface program. */ 573 struct { 574 GrGLuint fProgram; 575 GrGLint fTextureUniform; 576 GrGLint fTexCoordXformUniform; 577 GrGLint fPosXformUniform; 578 } fCopyPrograms[3]; 579 GrGLuint fCopyProgramArrayBuffer; 580 581 struct { 582 GrGLuint fProgram; 583 GrGLint fColorUniform; 584 GrGLint fRectUniform; 585 } fWireRectProgram; 586 GrGLuint fWireRectArrayBuffer; 587 588 static int TextureTargetToCopyProgramIdx(GrGLenum target) { 589 switch (target) { 590 case GR_GL_TEXTURE_2D: 591 return 0; 592 case GR_GL_TEXTURE_EXTERNAL: 593 return 1; 594 case GR_GL_TEXTURE_RECTANGLE: 595 return 2; 596 default: 597 SkFAIL("Unexpected texture target type."); 598 return 0; 599 } 600 } 601 602 struct { 603 GrGLuint fProgram; 604 GrGLint fPosXformUniform; 605 GrGLuint fArrayBuffer; 606 } fPLSSetupProgram; 607 608 bool fHWPLSEnabled; 609 bool fPLSHasBeenUsed; 610 611 typedef GrGpu INHERITED; 612 friend class GrGLPathRendering; // For accessing setTextureUnit. 613 }; 614 615 #endif 616