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