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