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 "GrGLPathRendering.h" 14 #include "GrGLProgram.h" 15 #include "GrGLRenderTarget.h" 16 #include "GrGLStencilAttachment.h" 17 #include "GrGLTexture.h" 18 #include "GrGLVertexArray.h" 19 #include "GrGpu.h" 20 #include "GrTexturePriv.h" 21 #include "GrWindowRectsState.h" 22 #include "GrXferProcessor.h" 23 #include "SkLRUCache.h" 24 #include "SkTArray.h" 25 #include "SkTypes.h" 26 27 class GrGLBuffer; 28 class GrPipeline; 29 class GrNonInstancedMesh; 30 class GrSwizzle; 31 32 namespace gr_instanced { class GLInstancedRendering; } 33 34 #ifdef SK_DEBUG 35 #define PROGRAM_CACHE_STATS 36 #endif 37 38 class GrGLGpu final : public GrGpu { 39 public: 40 static GrGpu* Create(GrBackendContext backendContext, const GrContextOptions& options, 41 GrContext* context); 42 ~GrGLGpu() override; 43 44 void disconnect(DisconnectType) override; 45 glContext()46 const GrGLContext& glContext() const { return *fGLContext; } 47 glInterface()48 const GrGLInterface* glInterface() const { return fGLContext->interface(); } ctxInfo()49 const GrGLContextInfo& ctxInfo() const { return *fGLContext; } glStandard()50 GrGLStandard glStandard() const { return fGLContext->standard(); } glVersion()51 GrGLVersion glVersion() const { return fGLContext->version(); } glslGeneration()52 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } glCaps()53 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 54 glPathRendering()55 GrGLPathRendering* glPathRendering() { 56 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 57 return static_cast<GrGLPathRendering*>(pathRendering()); 58 } 59 60 // Used by GrGLProgram to configure OpenGL state. 61 void bindTexture(int unitIdx, const GrSamplerParams& params, bool allowSRGBInputs, 62 GrGLTexture* texture); 63 64 void bindTexelBuffer(int unitIdx, GrPixelConfig, GrGLBuffer*); 65 66 void bindImageStorage(int unitIdx, GrIOType, GrGLTexture *); 67 68 void generateMipmaps(const GrSamplerParams& params, bool allowSRGBInputs, GrGLTexture* texture); 69 70 bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes, 71 GrPixelConfig readConfig, DrawPreference*, 72 ReadPixelTempDrawInfo*) override; 73 74 bool onGetWritePixelsInfo(GrSurface* dstSurface, int width, int height, 75 GrPixelConfig srcConfig, DrawPreference*, 76 WritePixelTempDrawInfo*) override; 77 78 // These functions should be used to bind GL objects. They track the GL state and skip redundant 79 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. bindVertexArray(GrGLuint id)80 void bindVertexArray(GrGLuint id) { 81 fHWVertexArrayState.setVertexArrayID(this, id); 82 } 83 84 // These callbacks update state tracking when GL objects are deleted. They are called from 85 // GrGLResource onRelease functions. notifyVertexArrayDelete(GrGLuint id)86 void notifyVertexArrayDelete(GrGLuint id) { 87 fHWVertexArrayState.notifyVertexArrayDelete(id); 88 } 89 90 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and 91 // returns the GL target the buffer was bound to. 92 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. 93 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. 94 GrGLenum bindBuffer(GrBufferType type, const GrBuffer*); 95 96 // Called by GrGLBuffer after its buffer object has been destroyed. 97 void notifyBufferReleased(const GrGLBuffer*); 98 99 // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu. 100 // Thus this is the implementation of the draw call for the corresponding passthrough function 101 // on GrGLGpuCommandBuffer. 102 void draw(const GrPipeline&, 103 const GrPrimitiveProcessor&, 104 const GrMesh*, 105 int meshCount); 106 107 // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu. 108 // Thus this is the implementation of the clear call for the corresponding passthrough function 109 // on GrGLGpuCommandBuffer. 110 void clear(const GrFixedClip&, GrColor, GrRenderTarget*); 111 112 // The GrGLGpuCommandBuffer does not buffer up draws before submitting them to the gpu. 113 // Thus this is the implementation of the clearStencil call for the corresponding passthrough 114 // function on GrGLGpuCommandBuffer. 115 void clearStencilClip(const GrFixedClip&, bool insideStencilMask, GrRenderTarget*); 116 glContextForTesting()117 const GrGLContext* glContextForTesting() const override { 118 return &this->glContext(); 119 } 120 121 void clearStencil(GrRenderTarget*) override; 122 123 GrGpuCommandBuffer* createCommandBuffer( 124 const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo, 125 const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) override; 126 invalidateBoundRenderTarget()127 void invalidateBoundRenderTarget() { 128 fHWBoundRenderTargetUniqueID.makeInvalid(); 129 } 130 131 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 132 int width, 133 int height) override; 134 135 GrBackendObject createTestingOnlyBackendTexture(void* pixels, int w, int h, 136 GrPixelConfig config, 137 bool isRenderTarget = false) override; 138 bool isTestingOnlyBackendTexture(GrBackendObject) const override; 139 void deleteTestingOnlyBackendTexture(GrBackendObject, bool abandonTexture) override; 140 141 void resetShaderCacheForTesting() const override; 142 143 void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override; 144 145 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 146 bool waitFence(GrFence, uint64_t timeout) override; 147 void deleteFence(GrFence) const override; 148 149 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore() override; 150 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override; 151 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override; 152 153 void deleteSync(GrGLsync) const; 154 155 void flush() override; 156 157 private: 158 GrGLGpu(GrGLContext* ctx, GrContext* context); 159 160 // GrGpu overrides 161 void onResetContext(uint32_t resetBits) override; 162 163 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 164 165 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 166 const SkTArray<GrMipLevel>& texels) override; 167 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, 168 SkBudgeted budgeted, 169 const SkTArray<GrMipLevel>& texels) override; 170 171 GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, 172 const void* data) override; 173 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override; 174 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override; 175 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTextureDesc&) override; 176 177 gr_instanced::InstancedRendering* onCreateInstancedRendering() override; 178 179 // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a 180 // compatible stencil format, or negative if there is no compatible stencil format. 181 int getCompatibleStencilIndex(GrPixelConfig config); 182 183 184 // Returns whether the texture is successfully created. On success, the 185 // result is stored in |info|. 186 // The texture is populated with |texels|, if it exists. 187 // The texture parameters are cached in |initialTexParams|. 188 bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, 189 bool renderTarget, GrGLTexture::TexParams* initialTexParams, 190 const SkTArray<GrMipLevel>& texels); 191 192 bool onIsACopyNeededForTextureParams(GrTextureProxy*, const GrSamplerParams&, 193 GrTextureProducer::CopyParams*, 194 SkScalar scaleAdjust[2]) const override; 195 196 // Checks whether glReadPixels can be called to get pixel values in readConfig from the 197 // render target. 198 bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig); 199 200 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 201 // render target that has renderTargetConfig. This may have to create a temporary 202 // render target and thus is less preferable than the variant that takes a render target. 203 bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig); 204 205 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 206 // render target that has the same config as surfaceForConfig. Calls one of the the two 207 // variations above, depending on whether the surface is a render target or not. 208 bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig); 209 210 bool onReadPixels(GrSurface*, 211 int left, int top, 212 int width, int height, 213 GrPixelConfig, 214 void* buffer, 215 size_t rowBytes) override; 216 217 bool onWritePixels(GrSurface*, 218 int left, int top, int width, int height, 219 GrPixelConfig config, 220 const SkTArray<GrMipLevel>& texels) override; 221 222 bool onTransferPixels(GrSurface*, 223 int left, int top, int width, int height, 224 GrPixelConfig config, GrBuffer* transferBuffer, 225 size_t offset, size_t rowBytes) override; 226 227 void onResolveRenderTarget(GrRenderTarget* target) override; 228 229 bool onCopySurface(GrSurface* dst, 230 GrSurface* src, 231 const SkIRect& srcRect, 232 const SkIPoint& dstPoint) override; 233 234 void onQueryMultisampleSpecs(GrRenderTarget*, const GrStencilSettings&, 235 int* effectiveSampleCnt, SamplePattern*) override; 236 237 // binds texture unit in GL 238 void setTextureUnit(int unitIdx); 239 240 void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]); 241 242 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. 243 // willDrawPoints must be true if point primitives will be rendered after setting the GL state. 244 bool flushGLState(const GrPipeline&, const GrPrimitiveProcessor&, bool willDrawPoints); 245 246 // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset 247 // an into the index buffer. It does not account for vertices.startIndex() but rather the start 248 // index is relative to the returned offset. 249 void setupGeometry(const GrPrimitiveProcessor&, 250 const GrNonInstancedMesh& mesh, 251 size_t* indexOffsetInBytes); 252 253 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 254 hasExtension(const char * ext)255 bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); } 256 257 bool copySurfaceAsDraw(GrSurface* dst, 258 GrSurface* src, 259 const SkIRect& srcRect, 260 const SkIPoint& dstPoint); 261 void copySurfaceAsCopyTexSubImage(GrSurface* dst, 262 GrSurface* src, 263 const SkIRect& srcRect, 264 const SkIPoint& dstPoint); 265 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, 266 GrSurface* src, 267 const SkIRect& srcRect, 268 const SkIPoint& dstPoint); 269 bool generateMipmap(GrGLTexture* texture, bool gammaCorrect); 270 271 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 272 273 class ProgramCache : public ::SkNoncopyable { 274 public: 275 ProgramCache(GrGLGpu* gpu); 276 ~ProgramCache(); 277 278 void abandon(); 279 GrGLProgram* refProgram(const GrGLGpu*, const GrPipeline&, const GrPrimitiveProcessor&, 280 bool hasPointSize); 281 282 private: 283 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 284 // shader before evicting from the cache. 285 static const int kMaxEntries = 128; 286 287 struct Entry; 288 289 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 290 // of the index of where it should be inserted. 291 int search(const GrProgramDesc& desc) const; 292 293 struct DescHash { operatorDescHash294 uint32_t operator()(const GrProgramDesc& desc) const { 295 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 296 } 297 }; 298 299 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 300 301 GrGLGpu* fGpu; 302 #ifdef PROGRAM_CACHE_STATS 303 int fTotalRequests; 304 int fCacheMisses; 305 int fHashMisses; // cache hit but hash table missed 306 #endif 307 }; 308 309 void flushColorWrite(bool writeColor); 310 void flushDrawFace(GrDrawFace face); 311 312 // flushes the scissor. see the note on flushBoundTextureAndParams about 313 // flushing the scissor after that function is called. 314 void flushScissor(const GrScissorState&, 315 const GrGLIRect& rtViewport, 316 GrSurfaceOrigin rtOrigin); 317 318 // disables the scissor 319 void disableScissor(); 320 321 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*); 322 void disableWindowRectangles(); 323 324 void initFSAASupport(); 325 326 // determines valid stencil formats 327 void initStencilFormats(); 328 329 // sets a texture unit to use for texture operations other than binding a texture to a program. 330 // ensures that such operations don't negatively interact with tracking bound textures. 331 void setScratchTextureUnit(); 332 333 // bounds is region that may be modified. 334 // nullptr means whole target. Can be an empty rect. 335 void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds, bool disableSRGB = false); 336 337 // Need not be called if flushRenderTarget is used. 338 void flushViewport(const GrGLIRect&); 339 340 void flushStencil(const GrStencilSettings&); 341 void disableStencil(); 342 343 // rt is used only if useHWAA is true. 344 void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled); 345 346 void flushMinSampleShading(float minSampleShading); 347 348 void flushFramebufferSRGB(bool enable); 349 350 // helper for onCreateTexture and writeTexturePixels 351 enum UploadType { 352 kNewTexture_UploadType, // we are creating a new texture 353 kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture 354 kTransfer_UploadType, // we are using a transfer buffer to copy data 355 }; 356 bool uploadTexData(const GrSurfaceDesc& desc, 357 GrGLenum target, 358 UploadType uploadType, 359 int left, int top, int width, int height, 360 GrPixelConfig dataConfig, 361 const SkTArray<GrMipLevel>& texels); 362 363 // helper for onCreateCompressedTexture. If width and height are 364 // set to -1, then this function will use desc.fWidth and desc.fHeight 365 // for the size of the data. The isNewTexture flag should be set to true 366 // whenever a new texture needs to be created. Otherwise, we assume that 367 // the texture is already in GPU memory and that it's going to be updated 368 // with new data. 369 bool uploadCompressedTexData(const GrSurfaceDesc& desc, 370 GrGLenum target, 371 const SkTArray<GrMipLevel>& texels, 372 UploadType uploadType = kNewTexture_UploadType, 373 int left = 0, int top = 0, 374 int width = -1, int height = -1); 375 376 bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo, 377 GrGLRenderTarget::IDDesc*); 378 379 enum TempFBOTarget { 380 kSrc_TempFBOTarget, 381 kDst_TempFBOTarget 382 }; 383 384 // Binds a surface as a FBO for copying or reading. If the surface already owns an FBO ID then 385 // that ID is bound. If not the surface is temporarily bound to a FBO and that FBO is bound. 386 // This must be paired with a call to unbindSurfaceFBOForPixelOps(). 387 void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 388 TempFBOTarget tempFBOTarget); 389 390 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 391 void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface); 392 393 sk_sp<GrGLContext> fGLContext; 394 395 bool createCopyProgram(GrTexture* srcTexture); 396 bool createMipmapProgram(int progIdx); 397 bool createWireRectProgram(); 398 399 // GL program-related state 400 ProgramCache* fProgramCache; 401 402 /////////////////////////////////////////////////////////////////////////// 403 ///@name Caching of GL State 404 ///@{ 405 int fHWActiveTextureUnitIdx; 406 GrGLuint fHWProgramID; 407 408 enum TriState { 409 kNo_TriState, 410 kYes_TriState, 411 kUnknown_TriState 412 }; 413 414 GrGLuint fTempSrcFBOID; 415 GrGLuint fTempDstFBOID; 416 417 GrGLuint fStencilClearFBOID; 418 419 // last scissor / viewport scissor state seen by the GL. 420 struct { 421 TriState fEnabled; 422 GrGLIRect fRect; invalidate__anon9c78b18a0108423 void invalidate() { 424 fEnabled = kUnknown_TriState; 425 fRect.invalidate(); 426 } 427 } fHWScissorSettings; 428 429 class { 430 public: valid()431 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } invalidate()432 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } knownDisabled()433 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } setDisabled()434 void setDisabled() { 435 fRTOrigin = kDefault_GrSurfaceOrigin; 436 fWindowState.setDisabled(); 437 } 438 set(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)439 void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 440 const GrWindowRectsState& windowState) { 441 fRTOrigin = rtOrigin; 442 fViewport = viewport; 443 fWindowState = windowState; 444 } 445 knownEqualTo(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)446 bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 447 const GrWindowRectsState& windowState) const { 448 if (!this->valid()) { 449 return false; 450 } 451 if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) { 452 return false; 453 } 454 return fWindowState == windowState; 455 } 456 457 private: 458 enum { kInvalidSurfaceOrigin = -1 }; 459 460 int fRTOrigin; 461 GrGLIRect fViewport; 462 GrWindowRectsState fWindowState; 463 } fHWWindowRectsState; 464 465 GrGLIRect fHWViewport; 466 467 /** 468 * Tracks vertex attrib array state. 469 */ 470 class HWVertexArrayState { 471 public: HWVertexArrayState()472 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 473 ~HWVertexArrayState()474 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 475 invalidate()476 void invalidate() { 477 fBoundVertexArrayIDIsValid = false; 478 fDefaultVertexArrayAttribState.invalidate(); 479 if (fCoreProfileVertexArray) { 480 fCoreProfileVertexArray->invalidateCachedState(); 481 } 482 } 483 notifyVertexArrayDelete(GrGLuint id)484 void notifyVertexArrayDelete(GrGLuint id) { 485 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 486 // Does implicit bind to 0 487 fBoundVertexArrayID = 0; 488 } 489 } 490 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)491 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 492 if (!gpu->glCaps().vertexArrayObjectSupport()) { 493 SkASSERT(0 == arrayID); 494 return; 495 } 496 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 497 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 498 fBoundVertexArrayIDIsValid = true; 499 fBoundVertexArrayID = arrayID; 500 } 501 } 502 503 /** 504 * Binds the vertex array that should be used for internal draws, and returns its attrib 505 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 506 * case we use a dummy array instead. 507 * 508 * If an index buffer is privided, it will be bound to the vertex array. Otherwise the 509 * index buffer binding will be left unchanged. 510 * 511 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 512 */ 513 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 514 515 private: 516 GrGLuint fBoundVertexArrayID; 517 bool fBoundVertexArrayIDIsValid; 518 519 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 520 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 521 // GrGLGpu. 522 GrGLAttribArrayState fDefaultVertexArrayAttribState; 523 524 // This is used when we're using a core profile. 525 GrGLVertexArray* fCoreProfileVertexArray; 526 } fHWVertexArrayState; 527 528 struct { 529 GrGLenum fGLTarget; 530 GrGpuResource::UniqueID fBoundBufferUniqueID; 531 bool fBufferZeroKnownBound; 532 invalidate__anon9c78b18a0308533 void invalidate() { 534 fBoundBufferUniqueID.makeInvalid(); 535 fBufferZeroKnownBound = false; 536 } 537 } fHWBufferState[kGrBufferTypeCount]; 538 539 struct { 540 GrBlendEquation fEquation; 541 GrBlendCoeff fSrcCoeff; 542 GrBlendCoeff fDstCoeff; 543 GrColor fConstColor; 544 bool fConstColorValid; 545 TriState fEnabled; 546 invalidate__anon9c78b18a0408547 void invalidate() { 548 fEquation = static_cast<GrBlendEquation>(-1); 549 fSrcCoeff = static_cast<GrBlendCoeff>(-1); 550 fDstCoeff = static_cast<GrBlendCoeff>(-1); 551 fConstColorValid = false; 552 fEnabled = kUnknown_TriState; 553 } 554 } fHWBlendState; 555 556 TriState fMSAAEnabled; 557 558 GrStencilSettings fHWStencilSettings; 559 TriState fHWStencilTestEnabled; 560 561 562 GrDrawFace fHWDrawFace; 563 TriState fHWWriteToColor; 564 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 565 TriState fHWSRGBFramebuffer; 566 SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs; 567 568 struct Image { 569 GrGpuResource::UniqueID fTextureUniqueID; 570 GrIOType fIOType; 571 }; 572 SkTArray<Image, true> fHWBoundImageStorages; 573 574 struct BufferTexture { BufferTextureBufferTexture575 BufferTexture() : fTextureID(0), fKnownBound(false), 576 fAttachedBufferUniqueID(SK_InvalidUniqueID), 577 fSwizzle(GrSwizzle::RGBA()) {} 578 579 GrGLuint fTextureID; 580 bool fKnownBound; 581 GrPixelConfig fTexelConfig; 582 GrGpuResource::UniqueID fAttachedBufferUniqueID; 583 GrSwizzle fSwizzle; 584 }; 585 586 SkTArray<BufferTexture, true> fHWBufferTextures; 587 int fHWMaxUsedBufferTextureUnit; 588 589 // EXT_raster_multisample. 590 TriState fHWRasterMultisampleEnabled; 591 int fHWNumRasterSamples; 592 ///@} 593 594 /** IDs for copy surface program. (4 sampler types) */ 595 struct { 596 GrGLuint fProgram; 597 GrGLint fTextureUniform; 598 GrGLint fTexCoordXformUniform; 599 GrGLint fPosXformUniform; 600 } fCopyPrograms[4]; 601 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 602 603 /** IDs for texture mipmap program. (4 filter configurations) */ 604 struct { 605 GrGLuint fProgram; 606 GrGLint fTextureUniform; 607 GrGLint fTexCoordXformUniform; 608 } fMipmapPrograms[4]; 609 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 610 611 struct { 612 GrGLuint fProgram; 613 GrGLint fColorUniform; 614 GrGLint fRectUniform; 615 } fWireRectProgram; 616 sk_sp<GrGLBuffer> fWireRectArrayBuffer; 617 TextureToCopyProgramIdx(GrTexture * texture)618 static int TextureToCopyProgramIdx(GrTexture* texture) { 619 switch (texture->texturePriv().samplerType()) { 620 case kTexture2DSampler_GrSLType: 621 return 0; 622 case kITexture2DSampler_GrSLType: 623 return 1; 624 case kTexture2DRectSampler_GrSLType: 625 return 2; 626 case kTextureExternalSampler_GrSLType: 627 return 3; 628 default: 629 SkFAIL("Unexpected samper type"); 630 return 0; 631 } 632 } 633 TextureSizeToMipmapProgramIdx(int width,int height)634 static int TextureSizeToMipmapProgramIdx(int width, int height) { 635 const bool wide = (width > 1) && SkToBool(width & 0x1); 636 const bool tall = (height > 1) && SkToBool(height & 0x1); 637 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 638 } 639 640 float fHWMinSampleShading; 641 642 typedef GrGpu INHERITED; 643 friend class GrGLPathRendering; // For accessing setTextureUnit. 644 friend class gr_instanced::GLInstancedRendering; // For accessing flushGLState. 645 }; 646 647 #endif 648