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