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