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