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 "include/core/SkTypes.h" 12 #include "include/private/base/SkTArray.h" 13 #include "src/core/SkLRUCache.h" 14 #include "src/gpu/ganesh/GrFinishCallbacks.h" 15 #include "src/gpu/ganesh/GrGpu.h" 16 #include "src/gpu/ganesh/GrNativeRect.h" 17 #include "src/gpu/ganesh/GrProgramDesc.h" 18 #include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h" 19 #include "src/gpu/ganesh/GrWindowRectsState.h" 20 #include "src/gpu/ganesh/GrXferProcessor.h" 21 #include "src/gpu/ganesh/gl/GrGLAttachment.h" 22 #include "src/gpu/ganesh/gl/GrGLContext.h" 23 #include "src/gpu/ganesh/gl/GrGLProgram.h" 24 #include "src/gpu/ganesh/gl/GrGLRenderTarget.h" 25 #include "src/gpu/ganesh/gl/GrGLTexture.h" 26 #include "src/gpu/ganesh/gl/GrGLVertexArray.h" 27 28 class GrGLBuffer; 29 class GrGLOpsRenderPass; 30 class GrPipeline; 31 32 namespace skgpu { 33 class Swizzle; 34 } 35 36 class GrGLGpu final : public GrGpu { 37 public: 38 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrDirectContext*); 39 ~GrGLGpu() override; 40 41 void disconnect(DisconnectType) override; 42 43 GrThreadSafePipelineBuilder* pipelineBuilder() override; 44 sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override; 45 glContext()46 const GrGLContext& glContext() const { return *fGLContext; } 47 glInterface()48 const GrGLInterface* glInterface() const { return fGLContext->glInterface(); } 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 SkSL::GLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } glCaps()53 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 54 stagingBufferManager()55 GrStagingBufferManager* stagingBufferManager() override { return fStagingBufferManager.get(); } 56 57 // Used by GrGLProgram to configure OpenGL state. 58 void bindTexture(int unitIdx, GrSamplerState samplerState, const skgpu::Swizzle&, GrGLTexture*); 59 60 // These functions should be used to bind GL objects. They track the GL state and skip redundant 61 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. bindVertexArray(GrGLuint id)62 void bindVertexArray(GrGLuint id) { 63 fHWVertexArrayState.setVertexArrayID(this, id); 64 } 65 66 // These callbacks update state tracking when GL objects are deleted. They are called from 67 // GrGLResource onRelease functions. notifyVertexArrayDelete(GrGLuint id)68 void notifyVertexArrayDelete(GrGLuint id) { 69 fHWVertexArrayState.notifyVertexArrayDelete(id); 70 } 71 72 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and 73 // returns the GL target the buffer was bound to. 74 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. 75 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. 76 GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*); 77 78 // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set. 79 bool flushGLState(GrRenderTarget*, bool useMultisampleFBO, const GrProgramInfo&); 80 void flushScissorRect(const SkIRect& scissor, int rtHeight, GrSurfaceOrigin); 81 82 // The flushRenderTarget methods will all set the initial viewport to the full extent of the 83 // backing render target. 84 void flushViewport(const SkIRect& viewport, int rtHeight, GrSurfaceOrigin); 85 86 // Returns the last program bound by flushGLState(), or nullptr if a different program has since 87 // been put into use via some other method (e.g., resetContext, copySurfaceAsDraw). 88 // The returned GrGLProgram can be used for binding textures and vertex attributes. currentProgram()89 GrGLProgram* currentProgram() { 90 this->handleDirtyContext(); 91 return fHWProgram.get(); 92 } 93 94 // Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex 95 // arrays, and flushes the desired primitive restart settings. If an index buffer is provided, 96 // it will be bound to the vertex array. Otherwise the index buffer binding will be left 97 // unchanged. 98 // 99 // NOTE: This binds the default VAO (ID=zero) unless we are on a core profile, in which case we 100 // use a placeholder array instead. bindInternalVertexArray(const GrBuffer * indexBuffer,int numAttribs,GrPrimitiveRestart primitiveRestart)101 GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, int numAttribs, 102 GrPrimitiveRestart primitiveRestart) { 103 auto* attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer); 104 attribState->enableVertexArrays(this, numAttribs, primitiveRestart); 105 return attribState; 106 } 107 108 // Applies any necessary workarounds and returns the GL primitive type to use in draw calls. 109 GrGLenum prepareToDraw(GrPrimitiveType primitiveType); 110 111 using ResolveDirection = GrGLRenderTarget::ResolveDirection; 112 113 // Resolves the render target's single sample FBO into the MSAA, or vice versa. 114 // If glCaps.framebufferResolvesMustBeFullSize() is true, resolveRect must be equal the render 115 // target's bounds rect. 116 // If blitting single to MSAA, glCaps.canResolveSingleToMSAA() must be true. 117 void resolveRenderFBOs(GrGLRenderTarget*, const SkIRect& resolveRect, ResolveDirection, 118 bool invalidateReadBufferAfterBlit = false); 119 120 // For loading a dynamic MSAA framebuffer when glCaps.canResolveSingleToMSAA() is false. 121 // NOTE: If glCaps.framebufferResolvesMustBeFullSize() is also true, the drawBounds should be 122 // equal to the proxy bounds. This is because the render pass will have to do a full size 123 // resolve back into the single sample FBO when rendering is complete. drawSingleIntoMSAAFBO(GrGLRenderTarget * rt,const SkIRect & drawBounds)124 void drawSingleIntoMSAAFBO(GrGLRenderTarget* rt, const SkIRect& drawBounds) { 125 this->copySurfaceAsDraw(rt, true/*drawToMultisampleFBO*/, rt, drawBounds, drawBounds, 126 GrSamplerState::Filter::kNearest); 127 } 128 129 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. 130 // Thus this is the implementation of the clear call for the corresponding passthrough function 131 // on GrGLOpsRenderPass. 132 void clear(const GrScissorState&, std::array<float, 4> color, GrRenderTarget*, 133 bool useMultisampleFBO, GrSurfaceOrigin); 134 135 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. 136 // Thus this is the implementation of the clearStencil call for the corresponding passthrough 137 // function on GrGLOpsrenderPass. 138 void clearStencilClip(const GrScissorState&, bool insideStencilMask, 139 GrRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin); 140 141 void beginCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO, 142 const SkIRect& bounds, GrSurfaceOrigin, 143 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, 144 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); 145 146 void endCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO, 147 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, 148 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); 149 invalidateBoundRenderTarget()150 void invalidateBoundRenderTarget() { 151 fHWBoundRenderTargetUniqueID.makeInvalid(); 152 } 153 154 sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat, 155 SkISize dimensions, int numStencilSamples) override; 156 157 sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions, 158 const GrBackendFormat& format, 159 int numSamples, 160 GrProtected isProtected, 161 GrMemoryless) override; 162 163 void deleteBackendTexture(const GrBackendTexture&) override; 164 165 bool compile(const GrProgramDesc&, const GrProgramInfo&) override; 166 precompileShader(const SkData & key,const SkData & data)167 bool precompileShader(const SkData& key, const SkData& data) override { 168 return fProgramCache->precompileShader(this->getContext(), key, data); 169 } 170 171 #if GR_TEST_UTILS 172 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 173 174 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions, 175 GrColorType, 176 int sampleCnt, 177 GrProtected) override; 178 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 179 glContextForTesting()180 const GrGLContext* glContextForTesting() const override { return &this->glContext(); } 181 resetShaderCacheForTesting()182 void resetShaderCacheForTesting() const override { fProgramCache->reset(); } 183 #endif 184 185 void willExecute() override; 186 187 void submit(GrOpsRenderPass* renderPass) override; 188 189 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 190 bool waitFence(GrFence) override; 191 void deleteFence(GrFence) override; 192 193 std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override; 194 std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&, 195 GrSemaphoreWrapType, 196 GrWrapOwnership) override; 197 void insertSemaphore(GrSemaphore* semaphore) override; 198 void waitSemaphore(GrSemaphore* semaphore) override; 199 200 void checkFinishProcs() override; 201 void finishOutstandingGpuWork() override; 202 203 // Calls glGetError() until no errors are reported. Also looks for OOMs. 204 void clearErrorsAndCheckForOOM(); 205 // Calls glGetError() once and returns the result. Also looks for an OOM. 206 GrGLenum getErrorAndCheckForOOM(); 207 208 std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 209 210 void deleteSync(GrGLsync); 211 212 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid); 213 void deleteFramebuffer(GrGLuint fboid); 214 215 void flushProgram(sk_sp<GrGLProgram>); 216 217 // Version for programs that aren't GrGLProgram. 218 void flushProgram(GrGLuint); 219 220 // GrGLOpsRenderPass directly makes GL draws. GrGLGpu uses this notification to mark the 221 // destination surface dirty if color writes are enabled. 222 void didDrawTo(GrRenderTarget*); 223 224 private: 225 GrGLGpu(std::unique_ptr<GrGLContext>, GrDirectContext*); 226 227 // GrGpu overrides 228 GrBackendTexture onCreateBackendTexture(SkISize dimensions, 229 const GrBackendFormat&, 230 GrRenderable, 231 GrMipmapped, 232 GrProtected, 233 std::string_view label) override; 234 235 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, 236 const GrBackendFormat&, 237 GrMipmapped, 238 GrProtected) override; 239 240 bool onClearBackendTexture(const GrBackendTexture&, 241 sk_sp<skgpu::RefCntedCallback> finishedCallback, 242 std::array<float, 4> color) override; 243 244 bool onUpdateCompressedBackendTexture(const GrBackendTexture&, 245 sk_sp<skgpu::RefCntedCallback> finishedCallback, 246 const void* data, 247 size_t length) override; 248 249 void onResetContext(uint32_t resetBits) override; 250 251 void onResetTextureBindings() override; 252 253 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 254 255 sk_sp<GrTexture> onCreateTexture(SkISize dimensions, 256 const GrBackendFormat&, 257 GrRenderable, 258 int renderTargetSampleCnt, 259 skgpu::Budgeted, 260 GrProtected, 261 int mipLevelCount, 262 uint32_t levelClearMask, 263 std::string_view label) override; 264 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, 265 const GrBackendFormat&, 266 skgpu::Budgeted, 267 GrMipmapped, 268 GrProtected, 269 const void* data, 270 size_t dataSize) override; 271 272 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType, GrAccessPattern) override; 273 274 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, 275 GrWrapOwnership, 276 GrWrapCacheable, 277 GrIOType) override; 278 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, 279 GrWrapOwnership, 280 GrWrapCacheable) override; 281 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 282 int sampleCnt, 283 GrWrapOwnership, 284 GrWrapCacheable) override; 285 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 286 287 // Given a GL format return the index into the stencil format array on GrGLCaps to a 288 // compatible stencil format, or negative if there is no compatible stencil format. 289 int getCompatibleStencilIndex(GrGLFormat format); 290 getPreferredStencilFormat(const GrBackendFormat & format)291 GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override { 292 int idx = this->getCompatibleStencilIndex(format.asGLFormat()); 293 if (idx < 0) { 294 return {}; 295 } 296 return GrBackendFormat::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]), 297 GR_GL_TEXTURE_NONE); 298 } 299 300 void onFBOChanged(); 301 302 // Returns whether the texture is successfully created. On success, a non-zero texture ID is 303 // returned. On failure, zero is returned. 304 // The texture is populated with |texels|, if it is non-null. 305 // The texture parameters are cached in |initialTexParams|. 306 GrGLuint createTexture(SkISize dimensions, 307 GrGLFormat, 308 GrGLenum target, 309 GrRenderable, 310 GrGLTextureParameters::SamplerOverriddenState*, 311 int mipLevelCount, 312 GrProtected isProtected, 313 std::string_view label); 314 315 GrGLuint createCompressedTexture2D(SkISize dimensions, 316 SkImage::CompressionType compression, 317 GrGLFormat, 318 GrMipmapped, 319 GrGLTextureParameters::SamplerOverriddenState*); 320 321 bool onReadPixels(GrSurface*, 322 SkIRect, 323 GrColorType surfaceColorType, 324 GrColorType dstColorType, 325 void*, 326 size_t rowBytes) override; 327 328 bool onWritePixels(GrSurface*, 329 SkIRect, 330 GrColorType surfaceColorType, 331 GrColorType srcColorType, 332 const GrMipLevel[], 333 int mipLevelCount, 334 bool prepForTexSampling) override; 335 336 bool onTransferFromBufferToBuffer(sk_sp<GrGpuBuffer> src, 337 size_t srcOffset, 338 sk_sp<GrGpuBuffer> dst, 339 size_t dstOffset, 340 size_t size) override; 341 342 bool onTransferPixelsTo(GrTexture*, 343 SkIRect, 344 GrColorType textureColorType, 345 GrColorType bufferColorType, 346 sk_sp<GrGpuBuffer>, 347 size_t offset, 348 size_t rowBytes) override; 349 350 bool onTransferPixelsFrom(GrSurface*, 351 SkIRect, 352 GrColorType surfaceColorType, 353 GrColorType bufferColorType, 354 sk_sp<GrGpuBuffer>, 355 size_t offset) override; 356 357 bool readOrTransferPixelsFrom(GrSurface*, 358 SkIRect rect, 359 GrColorType surfaceColorType, 360 GrColorType dstColorType, 361 void* offsetOrPtr, 362 int rowWidthInPixels); 363 364 // Unbinds xfer buffers from GL for operations that don't need them. 365 // Before calling any variation of TexImage, TexSubImage, etc..., call this with 366 // GrGpuBufferType::kXferCpuToGpu to ensure that the PIXEL_UNPACK_BUFFER is unbound. 367 // Before calling ReadPixels and reading back into cpu memory call this with 368 // GrGpuBufferType::kXferGpuToCpu to ensure that the PIXEL_PACK_BUFFER is unbound. 369 void unbindXferBuffer(GrGpuBufferType type); 370 371 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override; 372 373 bool onRegenerateMipMapLevels(GrTexture*) override; 374 375 bool onCopySurface(GrSurface* dst, const SkIRect& dstRect, 376 GrSurface* src, const SkIRect& srcRect, 377 GrSamplerState::Filter) override; 378 379 // binds texture unit in GL 380 void setTextureUnit(int unitIdx); 381 382 void flushBlendAndColorWrite(const skgpu::BlendInfo&, const skgpu::Swizzle&); 383 384 void addFinishedProc(GrGpuFinishedProc finishedProc, 385 GrGpuFinishedContext finishedContext) override; 386 387 GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*, 388 bool useMultisampleFBO, 389 GrAttachment*, 390 GrSurfaceOrigin, 391 const SkIRect&, 392 const GrOpsRenderPass::LoadAndStoreInfo&, 393 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 394 const SkTArray<GrSurfaceProxy*, true>& sampledProxies, 395 GrXferBarrierFlags renderPassXferBarriers) override; 396 397 bool onSubmitToGpu(bool syncCpu) override; 398 399 bool waitSync(GrGLsync, uint64_t timeout, bool flush); 400 401 bool copySurfaceAsDraw(GrSurface* dst, bool drawToMultisampleFBO, GrSurface* src, 402 const SkIRect& srcRect, const SkIRect& dstRect, GrSamplerState::Filter); 403 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 404 const SkIPoint& dstPoint); 405 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 406 const SkIRect& dstRect, GrSamplerState::Filter); 407 408 class ProgramCache : public GrThreadSafePipelineBuilder { 409 public: 410 ProgramCache(int runtimeProgramCacheSize); 411 ~ProgramCache() override; 412 413 void abandon(); 414 void reset(); 415 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*, 416 const GrProgramInfo&); 417 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*, 418 const GrProgramDesc&, 419 const GrProgramInfo&, 420 Stats::ProgramCacheResult*); 421 bool precompileShader(GrDirectContext*, const SkData& key, const SkData& data); 422 423 private: 424 struct Entry; 425 426 sk_sp<GrGLProgram> findOrCreateProgramImpl(GrDirectContext*, 427 const GrProgramDesc&, 428 const GrProgramInfo&, 429 Stats::ProgramCacheResult*); 430 431 struct DescHash { operatorDescHash432 uint32_t operator()(const GrProgramDesc& desc) const { 433 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 434 } 435 }; 436 437 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 438 }; 439 440 void flushColorWrite(bool writeColor); 441 void flushClearColor(std::array<float, 4>); 442 443 // flushes the scissor. see the note on flushBoundTextureAndParams about 444 // flushing the scissor after that function is called. flushScissor(const GrScissorState & scissorState,int rtHeight,GrSurfaceOrigin rtOrigin)445 void flushScissor(const GrScissorState& scissorState, int rtHeight, GrSurfaceOrigin rtOrigin) { 446 this->flushScissorTest(GrScissorTest(scissorState.enabled())); 447 if (scissorState.enabled()) { 448 this->flushScissorRect(scissorState.rect(), rtHeight, rtOrigin); 449 } 450 } 451 void flushScissorTest(GrScissorTest); 452 453 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); 454 void disableWindowRectangles(); 455 numTextureUnits()456 int numTextureUnits() const { return this->caps()->shaderCaps()->fMaxFragmentSamplers; } 457 458 // Binds a texture to a target on the "scratch" texture unit to use for texture operations 459 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It 460 // ensures that such operations don't negatively interact with draws. The active texture unit 461 // and the binding for 'target' will change. 462 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID); 463 464 void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO); 465 466 void flushStencil(const GrStencilSettings&, GrSurfaceOrigin); 467 void disableStencil(); 468 469 void flushConservativeRasterState(bool enable); 470 471 void flushWireframeState(bool enable); 472 473 void flushFramebufferSRGB(bool enable); 474 475 // Uploads src data of a color type to the currently bound texture on the active texture unit. 476 // The caller specifies color type that the texture is being used with, which may be different 477 // than the src color type. This fails if the combination of texture format, texture color type, 478 // and src data color type are not valid. No conversion is performed on the data before passing 479 // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1. 480 bool uploadColorTypeTexData(GrGLFormat textureFormat, 481 GrColorType textureColorType, 482 SkISize texDims, 483 GrGLenum target, 484 SkIRect dstRect, 485 GrColorType srcColorType, 486 const GrMipLevel texels[], 487 int mipLevelCount); 488 489 // Uploads a constant color to a texture using the "default" format and color type. Overwrites 490 // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This 491 // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits 492 // beyond the low bit set if the texture is not MIP mapped. 493 bool uploadColorToTex(GrGLFormat textureFormat, 494 SkISize texDims, 495 GrGLenum target, 496 std::array<float, 4> color, 497 uint32_t levelMask); 498 499 // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be 500 // the texture bounds if mipLevelCount is greater than 1. 501 void uploadTexData(SkISize dimensions, 502 GrGLenum target, 503 SkIRect dstRect, 504 GrGLenum externalFormat, 505 GrGLenum externalType, 506 size_t bpp, 507 const GrMipLevel texels[], 508 int mipLevelCount); 509 510 // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this 511 // to populate a new texture. Returns false if we failed to create and upload the texture. 512 bool uploadCompressedTexData(SkImage::CompressionType compressionType, 513 GrGLFormat, 514 SkISize dimensions, 515 GrMipmapped, 516 GrGLenum target, 517 const void* data, size_t dataSize); 518 519 // Calls one of various versions of renderBufferStorageMultisample. 520 bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format, 521 int width, int height); 522 523 bool createRenderTargetObjects(const GrGLTexture::Desc&, 524 int sampleCount, 525 GrGLRenderTarget::IDs*); 526 enum TempFBOTarget { 527 kSrc_TempFBOTarget, 528 kDst_TempFBOTarget 529 }; 530 531 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an 532 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO 533 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps(). 534 void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget, 535 TempFBOTarget tempFBOTarget); 536 537 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 538 void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget); 539 540 #ifdef SK_ENABLE_DUMP_GPU 541 void onDumpJSON(SkJSONWriter*) const override; 542 #endif 543 544 bool createCopyProgram(GrTexture* srcTexture); 545 bool createMipmapProgram(int progIdx); 546 547 std::unique_ptr<GrGLContext> fGLContext; 548 549 // GL program-related state 550 sk_sp<ProgramCache> fProgramCache; 551 552 /////////////////////////////////////////////////////////////////////////// 553 ///@name Caching of GL State 554 ///@{ 555 int fHWActiveTextureUnitIdx; 556 557 GrGLuint fHWProgramID; 558 sk_sp<GrGLProgram> fHWProgram; 559 560 enum TriState { 561 kNo_TriState, 562 kYes_TriState, 563 kUnknown_TriState 564 }; 565 566 GrGLuint fTempSrcFBOID; 567 GrGLuint fTempDstFBOID; 568 569 GrGLuint fStencilClearFBOID; 570 571 // last scissor / viewport scissor state seen by the GL. 572 struct { 573 TriState fEnabled; 574 GrNativeRect fRect; invalidate__anon497897140108575 void invalidate() { 576 fEnabled = kUnknown_TriState; 577 fRect.invalidate(); 578 } 579 } fHWScissorSettings; 580 581 class { 582 public: valid()583 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } invalidate()584 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } knownDisabled()585 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } setDisabled()586 void setDisabled() { 587 fRTOrigin = kTopLeft_GrSurfaceOrigin; 588 fWindowState.setDisabled(); 589 } 590 set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)591 void set(GrSurfaceOrigin rtOrigin, int width, int height, 592 const GrWindowRectsState& windowState) { 593 fRTOrigin = rtOrigin; 594 fWidth = width; 595 fHeight = height; 596 fWindowState = windowState; 597 } 598 knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)599 bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height, 600 const GrWindowRectsState& windowState) const { 601 if (!this->valid()) { 602 return false; 603 } 604 if (fWindowState.numWindows() && 605 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) { 606 return false; 607 } 608 return fWindowState == windowState; 609 } 610 611 private: 612 enum { kInvalidSurfaceOrigin = -1 }; 613 614 int fRTOrigin; 615 int fWidth; 616 int fHeight; 617 GrWindowRectsState fWindowState; 618 } fHWWindowRectsState; 619 620 GrNativeRect fHWViewport; 621 622 /** 623 * Tracks vertex attrib array state. 624 */ 625 class HWVertexArrayState { 626 public: HWVertexArrayState()627 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 628 ~HWVertexArrayState()629 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 630 invalidate()631 void invalidate() { 632 fBoundVertexArrayIDIsValid = false; 633 fDefaultVertexArrayAttribState.invalidate(); 634 if (fCoreProfileVertexArray) { 635 fCoreProfileVertexArray->invalidateCachedState(); 636 } 637 } 638 notifyVertexArrayDelete(GrGLuint id)639 void notifyVertexArrayDelete(GrGLuint id) { 640 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 641 // Does implicit bind to 0 642 fBoundVertexArrayID = 0; 643 } 644 } 645 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)646 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 647 if (!gpu->glCaps().vertexArrayObjectSupport()) { 648 SkASSERT(0 == arrayID); 649 return; 650 } 651 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 652 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 653 fBoundVertexArrayIDIsValid = true; 654 fBoundVertexArrayID = arrayID; 655 } 656 } 657 658 /** 659 * Binds the vertex array that should be used for internal draws, and returns its attrib 660 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 661 * case we use a placeholder array instead. 662 * 663 * If an index buffer is provided, it will be bound to the vertex array. Otherwise the 664 * index buffer binding will be left unchanged. 665 * 666 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 667 */ 668 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 669 670 private: 671 GrGLuint fBoundVertexArrayID; 672 bool fBoundVertexArrayIDIsValid; 673 674 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 675 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 676 // GrGLGpu. 677 GrGLAttribArrayState fDefaultVertexArrayAttribState; 678 679 // This is used when we're using a core profile. 680 GrGLVertexArray* fCoreProfileVertexArray; 681 } fHWVertexArrayState; 682 683 struct { 684 GrGLenum fGLTarget; 685 GrGpuResource::UniqueID fBoundBufferUniqueID; 686 bool fBufferZeroKnownBound; 687 invalidate__anon497897140308688 void invalidate() { 689 fBoundBufferUniqueID.makeInvalid(); 690 fBufferZeroKnownBound = false; 691 } 692 } fHWBufferState[kGrGpuBufferTypeCount]; 693 hwBufferState(GrGpuBufferType type)694 auto* hwBufferState(GrGpuBufferType type) { 695 unsigned typeAsUInt = static_cast<unsigned>(type); 696 SkASSERT(typeAsUInt < std::size(fHWBufferState)); 697 SkASSERT(type != GrGpuBufferType::kUniform); 698 return &fHWBufferState[typeAsUInt]; 699 } 700 701 enum class FlushType { 702 kIfRequired, 703 kForce, 704 }; 705 706 // This calls glFlush if it is required for previous operations or kForce is passed. 707 void flush(FlushType flushType = FlushType::kIfRequired); 708 setNeedsFlush()709 void setNeedsFlush() { fNeedsGLFlush = true; } 710 711 struct { 712 skgpu::BlendEquation fEquation; 713 skgpu::BlendCoeff fSrcCoeff; 714 skgpu::BlendCoeff fDstCoeff; 715 SkPMColor4f fConstColor; 716 bool fConstColorValid; 717 TriState fEnabled; 718 invalidate__anon497897140408719 void invalidate() { 720 fEquation = skgpu::BlendEquation::kIllegal; 721 fSrcCoeff = skgpu::BlendCoeff::kIllegal; 722 fDstCoeff = skgpu::BlendCoeff::kIllegal; 723 fConstColorValid = false; 724 fEnabled = kUnknown_TriState; 725 } 726 } fHWBlendState; 727 728 TriState fHWConservativeRasterEnabled; 729 730 TriState fHWWireframeEnabled; 731 732 GrStencilSettings fHWStencilSettings; 733 GrSurfaceOrigin fHWStencilOrigin; 734 TriState fHWStencilTestEnabled; 735 736 TriState fHWWriteToColor; 737 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 738 bool fHWBoundFramebufferIsMSAA; 739 TriState fHWSRGBFramebuffer; 740 741 class TextureUnitBindings { 742 public: 743 TextureUnitBindings() = default; 744 TextureUnitBindings(const TextureUnitBindings&) = delete; 745 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete; 746 747 GrGpuResource::UniqueID boundID(GrGLenum target) const; 748 bool hasBeenModified(GrGLenum target) const; 749 void setBoundID(GrGLenum target, GrGpuResource::UniqueID); 750 void invalidateForScratchUse(GrGLenum target); 751 void invalidateAllTargets(bool markUnmodified); 752 753 private: 754 struct TargetBinding { 755 GrGpuResource::UniqueID fBoundResourceID; 756 bool fHasBeenModified = false; 757 }; 758 TargetBinding fTargetBindings[3]; 759 }; 760 skia_private::AutoTArray<TextureUnitBindings> fHWTextureUnitBindings; 761 762 GrGLfloat fHWClearColor[4]; 763 764 GrGLuint fBoundDrawFramebuffer = 0; 765 766 /** IDs for copy surface program. (3 sampler types) */ 767 struct { 768 GrGLuint fProgram = 0; 769 GrGLint fTextureUniform = 0; 770 GrGLint fTexCoordXformUniform = 0; 771 GrGLint fPosXformUniform = 0; 772 } fCopyPrograms[3]; 773 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 774 775 /** IDs for texture mipmap program. (4 filter configurations) */ 776 struct { 777 GrGLuint fProgram = 0; 778 GrGLint fTextureUniform = 0; 779 GrGLint fTexCoordXformUniform = 0; 780 } fMipmapPrograms[4]; 781 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 782 783 static int TextureToCopyProgramIdx(GrTexture* texture); 784 TextureSizeToMipmapProgramIdx(int width,int height)785 static int TextureSizeToMipmapProgramIdx(int width, int height) { 786 const bool wide = (width > 1) && SkToBool(width & 0x1); 787 const bool tall = (height > 1) && SkToBool(height & 0x1); 788 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 789 } 790 791 GrPrimitiveType fLastPrimitiveType; 792 793 GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0; 794 795 class SamplerObjectCache; 796 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache; 797 798 std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass; 799 800 std::unique_ptr<GrStagingBufferManager> fStagingBufferManager; 801 802 GrFinishCallbacks fFinishCallbacks; 803 804 // If we've called a command that requires us to call glFlush than this will be set to true 805 // since we defer calling flush until submit time. When we call submitToGpu if this is true then 806 // we call glFlush and reset this to false. 807 bool fNeedsGLFlush = false; 808 809 SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false); 810 811 friend class GrGLPathRendering; // For accessing setTextureUnit. 812 813 using INHERITED = GrGpu; 814 }; 815 816 #endif 817