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 "GrMesh.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 GrGLGpuRTCommandBuffer; 29 class GrGLGpuTextureCommandBuffer; 30 class GrPipeline; 31 class GrSwizzle; 32 33 #ifdef SK_DEBUG 34 #define PROGRAM_CACHE_STATS 35 #endif 36 37 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl { 38 public: 39 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*); 40 ~GrGLGpu() override; 41 42 void disconnect(DisconnectType) override; 43 44 const GrGLContext& glContext() const { return *fGLContext; } 45 46 const GrGLInterface* glInterface() const { return fGLContext->interface(); } 47 const GrGLContextInfo& ctxInfo() const { return *fGLContext; } 48 GrGLStandard glStandard() const { return fGLContext->standard(); } 49 GrGLVersion glVersion() const { return fGLContext->version(); } 50 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } 51 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 52 53 GrGLPathRendering* glPathRendering() { 54 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 55 return static_cast<GrGLPathRendering*>(pathRendering()); 56 } 57 58 // Used by GrGLProgram to configure OpenGL state. 59 void bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture* texture); 60 61 // These functions should be used to bind GL objects. They track the GL state and skip redundant 62 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. 63 void bindVertexArray(GrGLuint id) { 64 fHWVertexArrayState.setVertexArrayID(this, id); 65 } 66 67 // These callbacks update state tracking when GL objects are deleted. They are called from 68 // GrGLResource onRelease functions. 69 void notifyVertexArrayDelete(GrGLuint id) { 70 fHWVertexArrayState.notifyVertexArrayDelete(id); 71 } 72 73 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and 74 // returns the GL target the buffer was bound to. 75 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. 76 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. 77 GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*); 78 79 // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. 80 // Thus this is the implementation of the draw call for the corresponding passthrough function 81 // on GrGLRTGpuCommandBuffer. 82 void draw(GrRenderTarget*, GrSurfaceOrigin, 83 const GrPrimitiveProcessor&, 84 const GrPipeline&, 85 const GrPipeline::FixedDynamicState*, 86 const GrPipeline::DynamicStateArrays*, 87 const GrMesh[], 88 int meshCount); 89 90 // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls. 91 // Marked final as a hint to the compiler to not use virtual dispatch. 92 void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, 93 int baseVertex) final; 94 95 void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, 96 int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, 97 const GrBuffer* vertexBuffer, int baseVertex, 98 GrPrimitiveRestart) final; 99 100 void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, 101 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, 102 int baseInstance) final; 103 104 void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, 105 int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, 106 const GrBuffer* instanceBuffer, int instanceCount, 107 int baseInstance, GrPrimitiveRestart) final; 108 109 // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. 110 // Thus this is the implementation of the clear call for the corresponding passthrough function 111 // on GrGLGpuRTCommandBuffer. 112 void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin); 113 114 // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. 115 // Thus this is the implementation of the clearStencil call for the corresponding passthrough 116 // function on GrGLGpuRTCommandBuffer. 117 void clearStencilClip(const GrFixedClip&, bool insideStencilMask, 118 GrRenderTarget*, GrSurfaceOrigin); 119 120 // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the 121 // stencil buffer as not dirty? 122 void clearStencil(GrRenderTarget*, int clearValue); 123 124 GrGpuRTCommandBuffer* getCommandBuffer( 125 GrRenderTarget*, GrSurfaceOrigin, const SkRect&, 126 const GrGpuRTCommandBuffer::LoadAndStoreInfo&, 127 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override; 128 129 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override; 130 131 void invalidateBoundRenderTarget() { 132 fHWBoundRenderTargetUniqueID.makeInvalid(); 133 } 134 135 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 136 int width, 137 int height) override; 138 #if GR_TEST_UTILS 139 GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h, 140 GrColorType colorType, bool isRenderTarget, 141 GrMipMapped mipMapped, 142 size_t rowBytes = 0) override; 143 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 144 void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; 145 146 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override; 147 148 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 149 150 const GrGLContext* glContextForTesting() const override { return &this->glContext(); } 151 152 void resetShaderCacheForTesting() const override { fProgramCache->abandon(); } 153 154 void testingOnly_flushGpuAndSync() override; 155 #endif 156 157 void submit(GrGpuCommandBuffer* buffer) override; 158 159 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 160 bool waitFence(GrFence, uint64_t timeout) override; 161 void deleteFence(GrFence) const override; 162 163 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override; 164 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore, 165 GrResourceProvider::SemaphoreWrapType wrapType, 166 GrWrapOwnership ownership) override; 167 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override; 168 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override; 169 170 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 171 172 void deleteSync(GrGLsync) const; 173 174 void insertEventMarker(const char*); 175 176 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid); 177 void deleteFramebuffer(GrGLuint fboid); 178 179 private: 180 GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*); 181 182 // GrGpu overrides 183 void onResetContext(uint32_t resetBits) override; 184 185 void onResetTextureBindings() override; 186 187 void querySampleLocations( 188 GrRenderTarget*, const GrStencilSettings&, SkTArray<SkPoint>*) override; 189 190 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 191 192 sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 193 const GrMipLevel texels[], int mipLevelCount) override; 194 195 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern, 196 const void* data) override; 197 198 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable, 199 GrIOType) override; 200 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, 201 GrWrapOwnership, GrWrapCacheable) override; 202 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 203 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, 204 int sampleCnt) override; 205 206 // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a 207 // compatible stencil format, or negative if there is no compatible stencil format. 208 int getCompatibleStencilIndex(GrPixelConfig config); 209 210 void onFBOChanged(); 211 212 // Returns whether the texture is successfully created. On success, the 213 // result is stored in |info|. 214 // The texture is populated with |texels|, if it exists. 215 // The texture parameters are cached in |initialTexParams|. 216 bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget, 217 GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[], 218 int mipLevelCount, GrMipMapsStatus* mipMapsStatus); 219 220 // Checks whether glReadPixels can be called to get pixel values in readConfig from the 221 // render target. 222 bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig); 223 224 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 225 // render target that has renderTargetConfig. This may have to create a temporary 226 // render target and thus is less preferable than the variant that takes a render target. 227 bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig); 228 229 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 230 // render target that has the same config as surfaceForConfig. Calls one of the the two 231 // variations above, depending on whether the surface is a render target or not. 232 bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig); 233 234 bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType, 235 void* buffer, size_t rowBytes) override; 236 237 bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType, 238 const GrMipLevel texels[], int mipLevelCount) override; 239 240 bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrColorType, 241 GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override; 242 243 // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the 244 // PIXEL_UNPACK_BUFFER is unbound. 245 void unbindCpuToGpuXferBuffer(); 246 247 void onResolveRenderTarget(GrRenderTarget* target) override; 248 249 bool onRegenerateMipMapLevels(GrTexture*) override; 250 251 bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, 252 GrSurface* src, GrSurfaceOrigin srcOrigin, 253 const SkIRect& srcRect, const SkIPoint& dstPoint, 254 bool canDiscardOutsideDstRect) override; 255 256 // binds texture unit in GL 257 void setTextureUnit(int unitIdx); 258 259 /** 260 * primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() * 261 * numPrimitiveProcessorTextureSets entries. 262 */ 263 void resolveAndGenerateMipMapsForProcessorTextures( 264 const GrPrimitiveProcessor&, const GrPipeline&, 265 const GrTextureProxy* const primitiveProcessorTextures[], 266 int numPrimitiveProcessorTextureSets); 267 268 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. 269 // willDrawPoints must be true if point primitives will be rendered after setting the GL state. 270 // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic 271 // state entries in each array. 272 bool flushGLState(GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&, 273 const GrPipeline&, const GrPipeline::FixedDynamicState*, 274 const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength, 275 bool willDrawPoints); 276 277 void flushProgram(sk_sp<GrGLProgram>); 278 279 // Version for programs that aren't GrGLProgram. 280 void flushProgram(GrGLuint); 281 282 // Sets up vertex/instance attribute pointers and strides. 283 void setupGeometry(const GrBuffer* indexBuffer, 284 const GrBuffer* vertexBuffer, 285 int baseVertex, 286 const GrBuffer* instanceBuffer, 287 int baseInstance, 288 GrPrimitiveRestart); 289 290 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 291 292 void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access, 293 GrFlushFlags flags, bool insertedSemaphores, 294 GrGpuFinishedProc finishedProc, 295 GrGpuFinishedContext finishedContext) override; 296 297 bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, 298 GrSurface* src, GrSurfaceOrigin srcOrigin, 299 const SkIRect& srcRect, const SkIPoint& dstPoint); 300 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, 301 GrSurface* src, GrSurfaceOrigin srcOrigin, 302 const SkIRect& srcRect, const SkIPoint& dstPoint); 303 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin, 304 GrSurface* src, GrSurfaceOrigin srcOrigin, 305 const SkIRect& srcRect, const SkIPoint& dstPoint); 306 307 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 308 309 class ProgramCache : public ::SkNoncopyable { 310 public: 311 ProgramCache(GrGLGpu* gpu); 312 ~ProgramCache(); 313 314 void abandon(); 315 GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin, 316 const GrPrimitiveProcessor&, 317 const GrTextureProxy* const primProcProxies[], 318 const GrPipeline&, bool hasPointSize); 319 320 private: 321 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 322 // shader before evicting from the cache. 323 static const int kMaxEntries = 128; 324 325 struct Entry; 326 327 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 328 // of the index of where it should be inserted. 329 int search(const GrProgramDesc& desc) const; 330 331 struct DescHash { 332 uint32_t operator()(const GrProgramDesc& desc) const { 333 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 334 } 335 }; 336 337 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 338 339 GrGLGpu* fGpu; 340 #ifdef PROGRAM_CACHE_STATS 341 int fTotalRequests; 342 int fCacheMisses; 343 int fHashMisses; // cache hit but hash table missed 344 #endif 345 }; 346 347 void flushColorWrite(bool writeColor); 348 void flushClearColor(GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a); 349 350 // flushes the scissor. see the note on flushBoundTextureAndParams about 351 // flushing the scissor after that function is called. 352 void flushScissor(const GrScissorState&, 353 const GrGLIRect& rtViewport, 354 GrSurfaceOrigin rtOrigin); 355 356 // disables the scissor 357 void disableScissor(); 358 359 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); 360 void disableWindowRectangles(); 361 362 int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); } 363 364 // Binds a texture to a target on the "scratch" texture unit to use for texture operations 365 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw 366 // GrMesh). It ensures that such operations don't negatively interact with draws. 367 // The active texture unit and the binding for 'target' will change. 368 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID); 369 370 // The passed bounds contains the render target's color values that will subsequently be 371 // written. 372 void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds); 373 // This version has an implicit bounds of the entire render target. 374 void flushRenderTarget(GrGLRenderTarget*); 375 // This version can be used when the render target's colors will not be written. 376 void flushRenderTargetNoColorWrites(GrGLRenderTarget*); 377 378 // Need not be called if flushRenderTarget is used. 379 void flushViewport(const GrGLIRect&); 380 381 void flushStencil(const GrStencilSettings&); 382 void disableStencil(); 383 384 // rt is used only if useHWAA is true. 385 void flushHWAAState(GrRenderTarget* rt, bool useHWAA); 386 387 void flushFramebufferSRGB(bool enable); 388 389 // helper for onCreateTexture and writeTexturePixels 390 enum UploadType { 391 kNewTexture_UploadType, // we are creating a new texture 392 kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture 393 }; 394 bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, GrGLenum target, 395 UploadType uploadType, int left, int top, int width, int height, 396 GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount, 397 GrMipMapsStatus* mipMapsStatus = nullptr); 398 399 // helper for onCreateCompressedTexture. Compressed textures are read-only so we 400 // only use this to populate a new texture. 401 bool uploadCompressedTexData(GrPixelConfig texConfig, int texWidth, int texHeight, 402 GrGLenum target, GrPixelConfig dataConfig, 403 const GrMipLevel texels[], int mipLevelCount, 404 GrMipMapsStatus* mipMapsStatus = nullptr); 405 406 bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo, 407 GrGLRenderTarget::IDDesc*); 408 409 enum TempFBOTarget { 410 kSrc_TempFBOTarget, 411 kDst_TempFBOTarget 412 }; 413 414 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an 415 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO 416 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps(). 417 void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 418 TempFBOTarget tempFBOTarget); 419 420 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 421 void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface); 422 423 #ifdef SK_ENABLE_DUMP_GPU 424 void onDumpJSON(SkJSONWriter*) const override; 425 #endif 426 427 bool createCopyProgram(GrTexture* srcTexture); 428 bool createMipmapProgram(int progIdx); 429 430 std::unique_ptr<GrGLContext> fGLContext; 431 432 // GL program-related state 433 ProgramCache* fProgramCache; 434 435 /////////////////////////////////////////////////////////////////////////// 436 ///@name Caching of GL State 437 ///@{ 438 int fHWActiveTextureUnitIdx; 439 440 GrGLuint fHWProgramID; 441 sk_sp<GrGLProgram> fHWProgram; 442 443 enum TriState { 444 kNo_TriState, 445 kYes_TriState, 446 kUnknown_TriState 447 }; 448 449 GrGLuint fTempSrcFBOID; 450 GrGLuint fTempDstFBOID; 451 452 GrGLuint fStencilClearFBOID; 453 454 // last scissor / viewport scissor state seen by the GL. 455 struct { 456 TriState fEnabled; 457 GrGLIRect fRect; 458 void invalidate() { 459 fEnabled = kUnknown_TriState; 460 fRect.invalidate(); 461 } 462 } fHWScissorSettings; 463 464 class { 465 public: 466 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } 467 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } 468 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } 469 void setDisabled() { 470 fRTOrigin = kTopLeft_GrSurfaceOrigin; 471 fWindowState.setDisabled(); 472 } 473 474 void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 475 const GrWindowRectsState& windowState) { 476 fRTOrigin = rtOrigin; 477 fViewport = viewport; 478 fWindowState = windowState; 479 } 480 481 bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 482 const GrWindowRectsState& windowState) const { 483 if (!this->valid()) { 484 return false; 485 } 486 if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) { 487 return false; 488 } 489 return fWindowState == windowState; 490 } 491 492 private: 493 enum { kInvalidSurfaceOrigin = -1 }; 494 495 int fRTOrigin; 496 GrGLIRect fViewport; 497 GrWindowRectsState fWindowState; 498 } fHWWindowRectsState; 499 500 GrGLIRect fHWViewport; 501 502 /** 503 * Tracks vertex attrib array state. 504 */ 505 class HWVertexArrayState { 506 public: 507 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 508 509 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 510 511 void invalidate() { 512 fBoundVertexArrayIDIsValid = false; 513 fDefaultVertexArrayAttribState.invalidate(); 514 if (fCoreProfileVertexArray) { 515 fCoreProfileVertexArray->invalidateCachedState(); 516 } 517 } 518 519 void notifyVertexArrayDelete(GrGLuint id) { 520 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 521 // Does implicit bind to 0 522 fBoundVertexArrayID = 0; 523 } 524 } 525 526 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 527 if (!gpu->glCaps().vertexArrayObjectSupport()) { 528 SkASSERT(0 == arrayID); 529 return; 530 } 531 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 532 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 533 fBoundVertexArrayIDIsValid = true; 534 fBoundVertexArrayID = arrayID; 535 } 536 } 537 538 /** 539 * Binds the vertex array that should be used for internal draws, and returns its attrib 540 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 541 * case we use a dummy array instead. 542 * 543 * If an index buffer is privided, it will be bound to the vertex array. Otherwise the 544 * index buffer binding will be left unchanged. 545 * 546 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 547 */ 548 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 549 550 private: 551 GrGLuint fBoundVertexArrayID; 552 bool fBoundVertexArrayIDIsValid; 553 554 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 555 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 556 // GrGLGpu. 557 GrGLAttribArrayState fDefaultVertexArrayAttribState; 558 559 // This is used when we're using a core profile. 560 GrGLVertexArray* fCoreProfileVertexArray; 561 } fHWVertexArrayState; 562 563 struct { 564 GrGLenum fGLTarget; 565 GrGpuResource::UniqueID fBoundBufferUniqueID; 566 bool fBufferZeroKnownBound; 567 568 void invalidate() { 569 fBoundBufferUniqueID.makeInvalid(); 570 fBufferZeroKnownBound = false; 571 } 572 } fHWBufferState[kGrGpuBufferTypeCount]; 573 574 auto* hwBufferState(GrGpuBufferType type) { 575 unsigned typeAsUInt = static_cast<unsigned>(type); 576 SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState)); 577 return &fHWBufferState[typeAsUInt]; 578 } 579 580 struct { 581 GrBlendEquation fEquation; 582 GrBlendCoeff fSrcCoeff; 583 GrBlendCoeff fDstCoeff; 584 SkPMColor4f fConstColor; 585 bool fConstColorValid; 586 TriState fEnabled; 587 588 void invalidate() { 589 fEquation = kIllegal_GrBlendEquation; 590 fSrcCoeff = kIllegal_GrBlendCoeff; 591 fDstCoeff = kIllegal_GrBlendCoeff; 592 fConstColorValid = false; 593 fEnabled = kUnknown_TriState; 594 } 595 } fHWBlendState; 596 597 TriState fMSAAEnabled; 598 599 GrStencilSettings fHWStencilSettings; 600 TriState fHWStencilTestEnabled; 601 602 603 TriState fHWWriteToColor; 604 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 605 TriState fHWSRGBFramebuffer; 606 607 class TextureUnitBindings { 608 public: 609 TextureUnitBindings() = default; 610 TextureUnitBindings(const TextureUnitBindings&) = delete; 611 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete; 612 613 GrGpuResource::UniqueID boundID(GrGLenum target) const; 614 bool hasBeenModified(GrGLenum target) const; 615 void setBoundID(GrGLenum target, GrGpuResource::UniqueID); 616 void invalidateForScratchUse(GrGLenum target); 617 void invalidateAllTargets(bool markUnmodified); 618 619 private: 620 struct TargetBinding { 621 GrGpuResource::UniqueID fBoundResourceID; 622 bool fHasBeenModified = false; 623 }; 624 TargetBinding fTargetBindings[3]; 625 }; 626 SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings; 627 628 GrGLfloat fHWClearColor[4]; 629 630 GrGLuint fBoundDrawFramebuffer = 0; 631 632 /** IDs for copy surface program. (3 sampler types) */ 633 struct { 634 GrGLuint fProgram = 0; 635 GrGLint fTextureUniform = 0; 636 GrGLint fTexCoordXformUniform = 0; 637 GrGLint fPosXformUniform = 0; 638 } fCopyPrograms[3]; 639 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 640 641 /** IDs for texture mipmap program. (4 filter configurations) */ 642 struct { 643 GrGLuint fProgram = 0; 644 GrGLint fTextureUniform = 0; 645 GrGLint fTexCoordXformUniform = 0; 646 } fMipmapPrograms[4]; 647 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 648 649 static int TextureToCopyProgramIdx(GrTexture* texture); 650 651 static int TextureSizeToMipmapProgramIdx(int width, int height) { 652 const bool wide = (width > 1) && SkToBool(width & 0x1); 653 const bool tall = (height > 1) && SkToBool(height & 0x1); 654 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 655 } 656 657 GrPrimitiveType fLastPrimitiveType; 658 659 class SamplerObjectCache; 660 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache; 661 662 std::unique_ptr<GrGLGpuRTCommandBuffer> fCachedRTCommandBuffer; 663 std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer; 664 665 friend class GrGLPathRendering; // For accessing setTextureUnit. 666 667 typedef GrGpu INHERITED; 668 }; 669 670 #endif 671