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 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, 260 const GrBackendFormat&, 261 SkBudgeted, 262 GrMipmapped, 263 GrProtected, 264 OH_NativeBuffer* nativeBuffer, 265 size_t bufferSize) override; 266 267 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern, 268 const void* data) override; 269 270 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, 271 GrWrapOwnership, 272 GrWrapCacheable, 273 GrIOType) override; 274 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, 275 GrWrapOwnership, 276 GrWrapCacheable) override; 277 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 278 int sampleCnt, 279 GrWrapOwnership, 280 GrWrapCacheable) override; 281 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 282 283 // Given a GL format return the index into the stencil format array on GrGLCaps to a 284 // compatible stencil format, or negative if there is no compatible stencil format. 285 int getCompatibleStencilIndex(GrGLFormat format); 286 getPreferredStencilFormat(const GrBackendFormat & format)287 GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override { 288 int idx = this->getCompatibleStencilIndex(format.asGLFormat()); 289 if (idx < 0) { 290 return {}; 291 } 292 return GrBackendFormat::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]), 293 GR_GL_TEXTURE_NONE); 294 } 295 296 void onFBOChanged(); 297 298 // Returns whether the texture is successfully created. On success, a non-zero texture ID is 299 // returned. On failure, zero is returned. 300 // The texture is populated with |texels|, if it is non-null. 301 // The texture parameters are cached in |initialTexParams|. 302 GrGLuint createTexture(SkISize dimensions, 303 GrGLFormat, 304 GrGLenum target, 305 GrRenderable, 306 GrGLTextureParameters::SamplerOverriddenState*, 307 int mipLevelCount); 308 309 GrGLuint createCompressedTexture2D(SkISize dimensions, 310 SkImage::CompressionType compression, 311 GrGLFormat, 312 GrMipmapped, 313 GrGLTextureParameters::SamplerOverriddenState*); 314 315 bool onReadPixels(GrSurface*, 316 SkIRect, 317 GrColorType surfaceColorType, 318 GrColorType dstColorType, 319 void*, 320 size_t rowBytes) override; 321 322 bool onWritePixels(GrSurface*, 323 SkIRect, 324 GrColorType surfaceColorType, 325 GrColorType srcColorType, 326 const GrMipLevel[], 327 int mipLevelCount, 328 bool prepForTexSampling) override; 329 330 bool onTransferPixelsTo(GrTexture*, 331 SkIRect, 332 GrColorType textureColorType, 333 GrColorType bufferColorType, 334 sk_sp<GrGpuBuffer>, 335 size_t offset, 336 size_t rowBytes) override; 337 338 bool onTransferPixelsFrom(GrSurface*, 339 SkIRect, 340 GrColorType surfaceColorType, 341 GrColorType bufferColorType, 342 sk_sp<GrGpuBuffer>, 343 size_t offset) override; 344 345 bool readOrTransferPixelsFrom(GrSurface*, 346 SkIRect rect, 347 GrColorType surfaceColorType, 348 GrColorType dstColorType, 349 void* offsetOrPtr, 350 int rowWidthInPixels); 351 352 // Unbinds xfer buffers from GL for operations that don't need them. 353 // Before calling any variation of TexImage, TexSubImage, etc..., call this with 354 // GrGpuBufferType::kXferCpuToGpu to ensure that the PIXEL_UNPACK_BUFFER is unbound. 355 // Before calling ReadPixels and reading back into cpu memory call this with 356 // GrGpuBufferType::kXferGpuToCpu to ensure that the PIXEL_PACK_BUFFER is unbound. 357 void unbindXferBuffer(GrGpuBufferType type); 358 359 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override; 360 361 bool onRegenerateMipMapLevels(GrTexture*) override; 362 363 bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 364 const SkIPoint& dstPoint) override; 365 366 // binds texture unit in GL 367 void setTextureUnit(int unitIdx); 368 369 void flushBlendAndColorWrite(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 370 371 void addFinishedProc(GrGpuFinishedProc finishedProc, 372 GrGpuFinishedContext finishedContext) override; 373 374 GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*, 375 bool useMultisampleFBO, 376 GrAttachment*, 377 GrSurfaceOrigin, 378 const SkIRect&, 379 const GrOpsRenderPass::LoadAndStoreInfo&, 380 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 381 const SkTArray<GrSurfaceProxy*, true>& sampledProxies, 382 GrXferBarrierFlags renderPassXferBarriers) override; 383 384 bool onSubmitToGpu(bool syncCpu) override; 385 386 bool waitSync(GrGLsync, uint64_t timeout, bool flush); 387 388 bool copySurfaceAsDraw(GrSurface* dst, bool drawToMultisampleFBO, GrSurface* src, 389 const SkIRect& srcRect, const SkIPoint& dstPoint); 390 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 391 const SkIPoint& dstPoint); 392 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 393 const SkIPoint& dstPoint); 394 395 class ProgramCache : public GrThreadSafePipelineBuilder { 396 public: 397 ProgramCache(int runtimeProgramCacheSize); 398 ~ProgramCache() override; 399 400 void abandon(); 401 void reset(); 402 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*, 403 const GrProgramInfo&); 404 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*, 405 const GrProgramDesc&, 406 const GrProgramInfo&, 407 Stats::ProgramCacheResult*); 408 bool precompileShader(GrDirectContext*, const SkData& key, const SkData& data); 409 410 private: 411 struct Entry; 412 413 sk_sp<GrGLProgram> findOrCreateProgramImpl(GrDirectContext*, 414 const GrProgramDesc&, 415 const GrProgramInfo&, 416 Stats::ProgramCacheResult*); 417 418 struct DescHash { operatorDescHash419 uint32_t operator()(const GrProgramDesc& desc) const { 420 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 421 } 422 }; 423 424 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 425 }; 426 427 void flushPatchVertexCount(uint8_t count); 428 429 void flushColorWrite(bool writeColor); 430 void flushClearColor(std::array<float, 4>); 431 432 // flushes the scissor. see the note on flushBoundTextureAndParams about 433 // flushing the scissor after that function is called. flushScissor(const GrScissorState & scissorState,int rtHeight,GrSurfaceOrigin rtOrigin)434 void flushScissor(const GrScissorState& scissorState, int rtHeight, GrSurfaceOrigin rtOrigin) { 435 this->flushScissorTest(GrScissorTest(scissorState.enabled())); 436 if (scissorState.enabled()) { 437 this->flushScissorRect(scissorState.rect(), rtHeight, rtOrigin); 438 } 439 } 440 void flushScissorTest(GrScissorTest); 441 442 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); 443 void disableWindowRectangles(); 444 numTextureUnits()445 int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); } 446 447 // Binds a texture to a target on the "scratch" texture unit to use for texture operations 448 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It 449 // ensures that such operations don't negatively interact with draws. The active texture unit 450 // and the binding for 'target' will change. 451 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID); 452 453 // The passed bounds contains the render target's color values that will subsequently be 454 // written. 455 void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin, 456 const SkIRect& bounds); 457 // This version has an implicit bounds of the entire render target. 458 void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO); 459 // This version can be used when the render target's colors will not be written. 460 void flushRenderTargetNoColorWrites(GrGLRenderTarget*, bool useMultisampleFBO); 461 462 void flushStencil(const GrStencilSettings&, GrSurfaceOrigin); 463 void disableStencil(); 464 465 void flushConservativeRasterState(bool enable); 466 467 void flushWireframeState(bool enable); 468 469 void flushFramebufferSRGB(bool enable); 470 471 // Uploads src data of a color type to the currently bound texture on the active texture unit. 472 // The caller specifies color type that the texture is being used with, which may be different 473 // than the src color type. This fails if the combination of texture format, texture color type, 474 // and src data color type are not valid. No conversion is performed on the data before passing 475 // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1. 476 bool uploadColorTypeTexData(GrGLFormat textureFormat, 477 GrColorType textureColorType, 478 SkISize texDims, 479 GrGLenum target, 480 SkIRect dstRect, 481 GrColorType srcColorType, 482 const GrMipLevel texels[], 483 int mipLevelCount); 484 485 // Uploads a constant color to a texture using the "default" format and color type. Overwrites 486 // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This 487 // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits 488 // beyond the low bit set if the texture is not MIP mapped. 489 bool uploadColorToTex(GrGLFormat textureFormat, 490 SkISize texDims, 491 GrGLenum target, 492 std::array<float, 4> color, 493 uint32_t levelMask); 494 495 // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be 496 // the texture bounds if mipLevelCount is greater than 1. 497 void uploadTexData(SkISize dimensions, 498 GrGLenum target, 499 SkIRect dstRect, 500 GrGLenum externalFormat, 501 GrGLenum externalType, 502 size_t bpp, 503 const GrMipLevel texels[], 504 int mipLevelCount); 505 506 // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this 507 // to populate a new texture. Returns false if we failed to create and upload the texture. 508 bool uploadCompressedTexData(SkImage::CompressionType compressionType, 509 GrGLFormat, 510 SkISize dimensions, 511 GrMipmapped, 512 GrGLenum target, 513 const void* data, size_t dataSize); 514 515 // Calls one of various versions of renderBufferStorageMultisample. 516 bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format, 517 int width, int height); 518 519 bool createRenderTargetObjects(const GrGLTexture::Desc&, 520 int sampleCount, 521 GrGLRenderTarget::IDs*); 522 enum TempFBOTarget { 523 kSrc_TempFBOTarget, 524 kDst_TempFBOTarget 525 }; 526 527 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an 528 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO 529 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps(). 530 void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget, 531 TempFBOTarget tempFBOTarget); 532 533 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 534 void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget); 535 536 #ifdef SK_ENABLE_DUMP_GPU 537 void onDumpJSON(SkJSONWriter*) const override; 538 #endif 539 540 bool createCopyProgram(GrTexture* srcTexture); 541 bool createMipmapProgram(int progIdx); 542 543 std::unique_ptr<GrGLContext> fGLContext; 544 545 // GL program-related state 546 sk_sp<ProgramCache> fProgramCache; 547 548 /////////////////////////////////////////////////////////////////////////// 549 ///@name Caching of GL State 550 ///@{ 551 int fHWActiveTextureUnitIdx; 552 553 GrGLuint fHWProgramID; 554 sk_sp<GrGLProgram> fHWProgram; 555 556 enum TriState { 557 kNo_TriState, 558 kYes_TriState, 559 kUnknown_TriState 560 }; 561 562 GrGLuint fTempSrcFBOID; 563 GrGLuint fTempDstFBOID; 564 565 GrGLuint fStencilClearFBOID; 566 567 // last scissor / viewport scissor state seen by the GL. 568 struct { 569 TriState fEnabled; 570 GrNativeRect fRect; invalidate__anon3048ca5b0108571 void invalidate() { 572 fEnabled = kUnknown_TriState; 573 fRect.invalidate(); 574 } 575 } fHWScissorSettings; 576 577 class { 578 public: valid()579 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } invalidate()580 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } knownDisabled()581 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } setDisabled()582 void setDisabled() { 583 fRTOrigin = kTopLeft_GrSurfaceOrigin; 584 fWindowState.setDisabled(); 585 } 586 set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)587 void set(GrSurfaceOrigin rtOrigin, int width, int height, 588 const GrWindowRectsState& windowState) { 589 fRTOrigin = rtOrigin; 590 fWidth = width; 591 fHeight = height; 592 fWindowState = windowState; 593 } 594 knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)595 bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height, 596 const GrWindowRectsState& windowState) const { 597 if (!this->valid()) { 598 return false; 599 } 600 if (fWindowState.numWindows() && 601 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) { 602 return false; 603 } 604 return fWindowState == windowState; 605 } 606 607 private: 608 enum { kInvalidSurfaceOrigin = -1 }; 609 610 int fRTOrigin; 611 int fWidth; 612 int fHeight; 613 GrWindowRectsState fWindowState; 614 } fHWWindowRectsState; 615 616 GrNativeRect fHWViewport; 617 618 /** 619 * Tracks vertex attrib array state. 620 */ 621 class HWVertexArrayState { 622 public: HWVertexArrayState()623 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 624 ~HWVertexArrayState()625 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 626 invalidate()627 void invalidate() { 628 fBoundVertexArrayIDIsValid = false; 629 fDefaultVertexArrayAttribState.invalidate(); 630 if (fCoreProfileVertexArray) { 631 fCoreProfileVertexArray->invalidateCachedState(); 632 } 633 } 634 notifyVertexArrayDelete(GrGLuint id)635 void notifyVertexArrayDelete(GrGLuint id) { 636 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 637 // Does implicit bind to 0 638 fBoundVertexArrayID = 0; 639 } 640 } 641 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)642 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 643 if (!gpu->glCaps().vertexArrayObjectSupport()) { 644 SkASSERT(0 == arrayID); 645 return; 646 } 647 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 648 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 649 fBoundVertexArrayIDIsValid = true; 650 fBoundVertexArrayID = arrayID; 651 } 652 } 653 654 /** 655 * Binds the vertex array that should be used for internal draws, and returns its attrib 656 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 657 * case we use a placeholder array instead. 658 * 659 * If an index buffer is provided, it will be bound to the vertex array. Otherwise the 660 * index buffer binding will be left unchanged. 661 * 662 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 663 */ 664 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 665 666 private: 667 GrGLuint fBoundVertexArrayID; 668 bool fBoundVertexArrayIDIsValid; 669 670 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 671 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 672 // GrGLGpu. 673 GrGLAttribArrayState fDefaultVertexArrayAttribState; 674 675 // This is used when we're using a core profile. 676 GrGLVertexArray* fCoreProfileVertexArray; 677 } fHWVertexArrayState; 678 679 uint8_t fHWPatchVertexCount; 680 681 struct { 682 GrGLenum fGLTarget; 683 GrGpuResource::UniqueID fBoundBufferUniqueID; 684 bool fBufferZeroKnownBound; 685 invalidate__anon3048ca5b0308686 void invalidate() { 687 fBoundBufferUniqueID.makeInvalid(); 688 fBufferZeroKnownBound = false; 689 } 690 } fHWBufferState[kGrGpuBufferTypeCount]; 691 hwBufferState(GrGpuBufferType type)692 auto* hwBufferState(GrGpuBufferType type) { 693 unsigned typeAsUInt = static_cast<unsigned>(type); 694 SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState)); 695 SkASSERT(type != GrGpuBufferType::kUniform); 696 return &fHWBufferState[typeAsUInt]; 697 } 698 699 enum class FlushType { 700 kIfRequired, 701 kForce, 702 }; 703 704 // This calls glFlush if it is required for previous operations or kForce is passed. 705 void flush(FlushType flushType = FlushType::kIfRequired); 706 setNeedsFlush()707 void setNeedsFlush() { fNeedsGLFlush = true; } 708 709 struct { 710 GrBlendEquation fEquation; 711 GrBlendCoeff fSrcCoeff; 712 GrBlendCoeff fDstCoeff; 713 SkPMColor4f fConstColor; 714 bool fConstColorValid; 715 TriState fEnabled; 716 invalidate__anon3048ca5b0408717 void invalidate() { 718 fEquation = kIllegal_GrBlendEquation; 719 fSrcCoeff = kIllegal_GrBlendCoeff; 720 fDstCoeff = kIllegal_GrBlendCoeff; 721 fConstColorValid = false; 722 fEnabled = kUnknown_TriState; 723 } 724 } fHWBlendState; 725 726 TriState fHWConservativeRasterEnabled; 727 728 TriState fHWWireframeEnabled; 729 730 GrStencilSettings fHWStencilSettings; 731 GrSurfaceOrigin fHWStencilOrigin; 732 TriState fHWStencilTestEnabled; 733 734 TriState fHWWriteToColor; 735 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 736 bool fHWBoundFramebufferIsMSAA; 737 TriState fHWSRGBFramebuffer; 738 739 class TextureUnitBindings { 740 public: 741 TextureUnitBindings() = default; 742 TextureUnitBindings(const TextureUnitBindings&) = delete; 743 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete; 744 745 GrGpuResource::UniqueID boundID(GrGLenum target) const; 746 bool hasBeenModified(GrGLenum target) const; 747 void setBoundID(GrGLenum target, GrGpuResource::UniqueID); 748 void invalidateForScratchUse(GrGLenum target); 749 void invalidateAllTargets(bool markUnmodified); 750 751 private: 752 struct TargetBinding { 753 GrGpuResource::UniqueID fBoundResourceID; 754 bool fHasBeenModified = false; 755 }; 756 TargetBinding fTargetBindings[3]; 757 }; 758 SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings; 759 760 GrGLfloat fHWClearColor[4]; 761 762 GrGLuint fBoundDrawFramebuffer = 0; 763 764 /** IDs for copy surface program. (3 sampler types) */ 765 struct { 766 GrGLuint fProgram = 0; 767 GrGLint fTextureUniform = 0; 768 GrGLint fTexCoordXformUniform = 0; 769 GrGLint fPosXformUniform = 0; 770 } fCopyPrograms[3]; 771 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 772 773 /** IDs for texture mipmap program. (4 filter configurations) */ 774 struct { 775 GrGLuint fProgram = 0; 776 GrGLint fTextureUniform = 0; 777 GrGLint fTexCoordXformUniform = 0; 778 } fMipmapPrograms[4]; 779 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 780 781 static int TextureToCopyProgramIdx(GrTexture* texture); 782 TextureSizeToMipmapProgramIdx(int width,int height)783 static int TextureSizeToMipmapProgramIdx(int width, int height) { 784 const bool wide = (width > 1) && SkToBool(width & 0x1); 785 const bool tall = (height > 1) && SkToBool(height & 0x1); 786 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 787 } 788 789 GrPrimitiveType fLastPrimitiveType; 790 791 GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0; 792 793 class SamplerObjectCache; 794 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache; 795 796 std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass; 797 GrFinishCallbacks fFinishCallbacks; 798 799 // If we've called a command that requires us to call glFlush than this will be set to true 800 // since we defer calling flush until submit time. When we call submitToGpu if this is true then 801 // we call glFlush and reset this to false. 802 bool fNeedsGLFlush = false; 803 804 SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false); 805 806 friend class GrGLPathRendering; // For accessing setTextureUnit. 807 808 using INHERITED = GrGpu; 809 }; 810 811 #endif 812