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 <list> 12 #include "include/core/SkTypes.h" 13 #include "include/private/SkTArray.h" 14 #include "src/core/SkLRUCache.h" 15 #include "src/gpu/GrGpu.h" 16 #include "src/gpu/GrMesh.h" 17 #include "src/gpu/GrNativeRect.h" 18 #include "src/gpu/GrProgramDesc.h" 19 #include "src/gpu/GrWindowRectsState.h" 20 #include "src/gpu/GrXferProcessor.h" 21 #include "src/gpu/gl/GrGLContext.h" 22 #include "src/gpu/gl/GrGLPathRendering.h" 23 #include "src/gpu/gl/GrGLProgram.h" 24 #include "src/gpu/gl/GrGLRenderTarget.h" 25 #include "src/gpu/gl/GrGLStencilAttachment.h" 26 #include "src/gpu/gl/GrGLTexture.h" 27 #include "src/gpu/gl/GrGLVertexArray.h" 28 29 class GrGLBuffer; 30 class GrGLOpsRenderPass; 31 class GrPipeline; 32 class GrSwizzle; 33 34 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl { 35 public: 36 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*); 37 ~GrGLGpu() override; 38 39 void disconnect(DisconnectType) override; 40 glContext()41 const GrGLContext& glContext() const { return *fGLContext; } 42 glInterface()43 const GrGLInterface* glInterface() const { return fGLContext->glInterface(); } ctxInfo()44 const GrGLContextInfo& ctxInfo() const { return *fGLContext; } glStandard()45 GrGLStandard glStandard() const { return fGLContext->standard(); } glVersion()46 GrGLVersion glVersion() const { return fGLContext->version(); } glslGeneration()47 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } glCaps()48 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 49 glPathRendering()50 GrGLPathRendering* glPathRendering() { 51 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 52 return static_cast<GrGLPathRendering*>(pathRendering()); 53 } 54 55 // Used by GrGLProgram to configure OpenGL state. 56 void bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle&, GrGLTexture*); 57 58 // These functions should be used to bind GL objects. They track the GL state and skip redundant 59 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. bindVertexArray(GrGLuint id)60 void bindVertexArray(GrGLuint id) { 61 fHWVertexArrayState.setVertexArrayID(this, id); 62 } 63 64 // These callbacks update state tracking when GL objects are deleted. They are called from 65 // GrGLResource onRelease functions. notifyVertexArrayDelete(GrGLuint id)66 void notifyVertexArrayDelete(GrGLuint id) { 67 fHWVertexArrayState.notifyVertexArrayDelete(id); 68 } 69 70 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and 71 // returns the GL target the buffer was bound to. 72 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. 73 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. 74 GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*); 75 76 // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set. 77 bool flushGLState(GrRenderTarget*, const GrProgramInfo&); 78 79 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. 80 // Thus this is the implementation of the draw call for the corresponding passthrough function 81 // on GrGLOpsRenderPass. 82 // 83 // The client must call flushGLState before this method. 84 void drawMeshes(GrRenderTarget*, const GrProgramInfo&, const GrMesh[], int meshCount); 85 86 // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls. 87 // Marked final as a hint to the compiler to not use virtual dispatch. 88 void sendArrayMeshToGpu(GrPrimitiveType primitiveType, const GrMesh&, int vertexCount, 89 int baseVertex) final; 90 void sendIndexedMeshToGpu(GrPrimitiveType, const GrMesh&, int indexCount, int baseIndex, 91 uint16_t minIndexValue, uint16_t maxIndexValue, int baseVertex) final; 92 void sendInstancedMeshToGpu(GrPrimitiveType, const GrMesh&, int vertexCount, int baseVertex, 93 int instanceCount, int baseInstance) final; 94 void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrMesh&, int indexCount, 95 int baseIndex, int baseVertex, int instanceCount, 96 int baseInstance) final; 97 98 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. 99 // Thus this is the implementation of the clear call for the corresponding passthrough function 100 // on GrGLOpsRenderPass. 101 void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin); 102 103 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu. 104 // Thus this is the implementation of the clearStencil call for the corresponding passthrough 105 // function on GrGLOpsrenderPass. 106 void clearStencilClip(const GrFixedClip&, bool insideStencilMask, 107 GrRenderTarget*, GrSurfaceOrigin); 108 109 // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the 110 // stencil buffer as not dirty? 111 void clearStencil(GrRenderTarget*, int clearValue); 112 113 void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin, 114 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, 115 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); 116 117 void endCommandBuffer(GrRenderTarget*, const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore, 118 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore); 119 120 GrOpsRenderPass* getOpsRenderPass( 121 GrRenderTarget*, GrSurfaceOrigin, const SkIRect&, 122 const GrOpsRenderPass::LoadAndStoreInfo&, 123 const GrOpsRenderPass::StencilLoadAndStoreInfo&, 124 const SkTArray<GrSurfaceProxy*, true>& sampledProxies) override; 125 invalidateBoundRenderTarget()126 void invalidateBoundRenderTarget() { 127 fHWBoundRenderTargetUniqueID.makeInvalid(); 128 } 129 130 GrStencilAttachment* createStencilAttachmentForRenderTarget( 131 const GrRenderTarget* rt, int width, int height, int numStencilSamples) override; 132 void deleteBackendTexture(const GrBackendTexture&) override; 133 compile(const GrProgramDesc & desc,const GrProgramInfo & programInfo)134 bool compile(const GrProgramDesc& desc, const GrProgramInfo& programInfo) override { 135 sk_sp<GrGLProgram> tmp = fProgramCache->findOrCreateProgram(desc, programInfo); 136 return SkToBool(tmp); 137 } 138 precompileShader(const SkData & key,const SkData & data)139 bool precompileShader(const SkData& key, const SkData& data) override { 140 return fProgramCache->precompileShader(key, data); 141 } 142 143 #if GR_TEST_UTILS 144 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 145 146 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override; 147 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 148 glContextForTesting()149 const GrGLContext* glContextForTesting() const override { return &this->glContext(); } 150 resetShaderCacheForTesting()151 void resetShaderCacheForTesting() const override { fProgramCache->reset(); } 152 153 void testingOnly_flushGpuAndSync() override; 154 #endif 155 156 void submit(GrOpsRenderPass* renderPass) override; 157 158 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 159 bool waitFence(GrFence, uint64_t timeout) override; 160 void deleteFence(GrFence) const override; 161 162 std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override; 163 std::unique_ptr<GrSemaphore> wrapBackendSemaphore( 164 const GrBackendSemaphore& semaphore, 165 GrResourceProvider::SemaphoreWrapType wrapType, 166 GrWrapOwnership ownership) override; 167 void insertSemaphore(GrSemaphore* semaphore) override; 168 void waitSemaphore(GrSemaphore* semaphore) override; 169 170 void checkFinishProcs() override; 171 172 std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 173 174 void deleteSync(GrGLsync) const; 175 176 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid); 177 void deleteFramebuffer(GrGLuint fboid); 178 179 void insertManualFramebufferBarrier() override; 180 181 private: 182 GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*); 183 184 // GrGpu overrides 185 GrBackendTexture onCreateBackendTexture(SkISize dimensions, 186 const GrBackendFormat&, 187 GrRenderable, 188 GrMipMapped, 189 GrProtected, 190 const BackendTextureData*) override; 191 192 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, 193 const GrBackendFormat&, 194 GrMipMapped, 195 GrProtected, 196 const BackendTextureData*) override; 197 198 void onResetContext(uint32_t resetBits) override; 199 200 void onResetTextureBindings() override; 201 202 void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override; 203 204 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 205 206 sk_sp<GrTexture> onCreateTexture(SkISize dimensions, 207 const GrBackendFormat&, 208 GrRenderable, 209 int renderTargetSampleCnt, 210 SkBudgeted, 211 GrProtected, 212 int mipLevelCount, 213 uint32_t levelClearMask) override; 214 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions, 215 const GrBackendFormat&, 216 SkBudgeted, 217 GrMipMapped, 218 GrProtected, 219 const void* data, size_t dataSize) override; 220 221 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern, 222 const void* data) override; 223 224 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership, 225 GrWrapCacheable, GrIOType) override; 226 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&, GrWrapOwnership, 227 GrWrapCacheable) override; 228 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, 229 GrColorType, GrWrapOwnership, 230 GrWrapCacheable) override; 231 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&, 232 GrColorType) override; 233 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, 234 int sampleCnt, GrColorType) override; 235 236 // Given a GL format return the index into the stencil format array on GrGLCaps to a 237 // compatible stencil format, or negative if there is no compatible stencil format. 238 int getCompatibleStencilIndex(GrGLFormat format); 239 240 void onFBOChanged(); 241 242 // Returns whether the texture is successfully created. On success, a non-zero texture ID is 243 // returned. On failure, zero is returned. 244 // The texture is populated with |texels|, if it is non-null. 245 // The texture parameters are cached in |initialTexParams|. 246 GrGLuint createTexture2D(SkISize dimensions, 247 GrGLFormat, 248 GrRenderable, 249 GrGLTextureParameters::SamplerOverriddenState*, 250 int mipLevelCount); 251 252 GrGLuint createCompressedTexture2D(SkISize dimensions, 253 GrGLFormat, 254 GrMipMapped, 255 GrGLTextureParameters::SamplerOverriddenState*, 256 const void* data, size_t dataSize); 257 258 bool onReadPixels(GrSurface*, int left, int top, int width, int height, 259 GrColorType surfaceColorType, GrColorType dstColorType, void* buffer, 260 size_t rowBytes) override; 261 262 bool onWritePixels(GrSurface*, int left, int top, int width, int height, 263 GrColorType surfaceColorType, GrColorType srcColorType, 264 const GrMipLevel texels[], int mipLevelCount, 265 bool prepForTexSampling) override; 266 267 bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height, 268 GrColorType textureColorType, GrColorType bufferColorType, 269 GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override; 270 bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height, 271 GrColorType surfaceColorType, GrColorType bufferColorType, 272 GrGpuBuffer* transferBuffer, size_t offset) override; 273 bool readOrTransferPixelsFrom(GrSurface*, int left, int top, int width, int height, 274 GrColorType surfaceColorType, GrColorType dstColorType, 275 void* offsetOrPtr, int rowWidthInPixels); 276 277 // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the 278 // PIXEL_UNPACK_BUFFER is unbound. 279 void unbindCpuToGpuXferBuffer(); 280 281 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect, 282 ForExternalIO) override; 283 284 bool onRegenerateMipMapLevels(GrTexture*) override; 285 286 bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 287 const SkIPoint& dstPoint) override; 288 289 // binds texture unit in GL 290 void setTextureUnit(int unitIdx); 291 292 void flushProgram(sk_sp<GrGLProgram>); 293 294 // Version for programs that aren't GrGLProgram. 295 void flushProgram(GrGLuint); 296 297 // Sets up vertex/instance attribute pointers and strides. 298 void setupGeometry(const GrBuffer* indexBuffer, 299 const GrBuffer* vertexBuffer, 300 int baseVertex, 301 const GrBuffer* instanceBuffer, 302 int baseInstance, 303 GrPrimitiveRestart); 304 305 void flushBlendAndColorWrite(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 306 307 bool onFinishFlush(GrSurfaceProxy*[], int n, SkSurface::BackendSurfaceAccess access, 308 const GrFlushInfo&, const GrPrepareForExternalIORequests&) override; 309 310 bool waitSync(GrGLsync, uint64_t timeout, bool flush); 311 312 bool copySurfaceAsDraw(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 313 const SkIPoint& dstPoint); 314 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 315 const SkIPoint& dstPoint); 316 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 317 const SkIPoint& dstPoint); 318 319 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 320 321 class ProgramCache : public ::SkNoncopyable { 322 public: 323 ProgramCache(GrGLGpu* gpu); 324 ~ProgramCache(); 325 326 void abandon(); 327 void reset(); 328 sk_sp<GrGLProgram> findOrCreateProgram(GrRenderTarget*, const GrProgramInfo&); findOrCreateProgram(const GrProgramDesc & desc,const GrProgramInfo & programInfo)329 sk_sp<GrGLProgram> findOrCreateProgram(const GrProgramDesc& desc, 330 const GrProgramInfo& programInfo) { 331 return this->findOrCreateProgram(nullptr, desc, programInfo); 332 } 333 bool precompileShader(const SkData& key, const SkData& data); 334 335 private: 336 struct Entry; 337 338 sk_sp<GrGLProgram> findOrCreateProgram(GrRenderTarget*, 339 const GrProgramDesc&, 340 const GrProgramInfo&); 341 342 struct DescHash { operatorDescHash343 uint32_t operator()(const GrProgramDesc& desc) const { 344 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 345 } 346 }; 347 348 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 349 350 GrGLGpu* fGpu; 351 }; 352 353 void flushPatchVertexCount(uint8_t count); 354 355 void flushColorWrite(bool writeColor); 356 void flushClearColor(const SkPMColor4f&); 357 358 // flushes the scissor. see the note on flushBoundTextureAndParams about 359 // flushing the scissor after that function is called. 360 void flushScissor(const GrScissorState&, int rtWidth, int rtHeight, GrSurfaceOrigin rtOrigin); 361 362 // disables the scissor 363 void disableScissor(); 364 365 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); 366 void disableWindowRectangles(); 367 numTextureUnits()368 int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); } 369 370 // Binds a texture to a target on the "scratch" texture unit to use for texture operations 371 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw 372 // GrMesh). It ensures that such operations don't negatively interact with draws. 373 // The active texture unit and the binding for 'target' will change. 374 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID); 375 376 // The passed bounds contains the render target's color values that will subsequently be 377 // written. 378 void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds); 379 // This version has an implicit bounds of the entire render target. 380 void flushRenderTarget(GrGLRenderTarget*); 381 // This version can be used when the render target's colors will not be written. 382 void flushRenderTargetNoColorWrites(GrGLRenderTarget*); 383 384 // Need not be called if flushRenderTarget is used. 385 void flushViewport(int width, int height); 386 387 void flushStencil(const GrStencilSettings&, GrSurfaceOrigin); 388 void disableStencil(); 389 390 // rt is used only if useHWAA is true. 391 void flushHWAAState(GrRenderTarget* rt, bool useHWAA); 392 393 void flushConservativeRasterState(bool enable); 394 395 void flushWireframeState(bool enable); 396 397 void flushFramebufferSRGB(bool enable); 398 399 bool uploadTexData(GrGLFormat textureFormat, GrColorType textureColorType, int texWidth, 400 int texHeight, GrGLenum target, int left, int top, int width, int height, 401 GrColorType srcColorType, const GrMipLevel texels[], int mipLevelCount, 402 GrMipMapsStatus* mipMapsStatus = nullptr); 403 404 // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this 405 // to populate a new texture. Returns false if we failed to create and upload the texture. 406 bool uploadCompressedTexData(GrGLFormat, 407 SkISize dimensions, 408 GrMipMapped, 409 GrGLenum target, 410 const void* data, size_t dataSize); 411 412 bool createRenderTargetObjects(const GrGLTexture::Desc&, 413 int sampleCount, 414 GrGLRenderTarget::IDs*); 415 416 enum TempFBOTarget { 417 kSrc_TempFBOTarget, 418 kDst_TempFBOTarget 419 }; 420 421 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an 422 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO 423 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps(). 424 void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget, 425 TempFBOTarget tempFBOTarget); 426 427 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 428 void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget); 429 430 #ifdef SK_ENABLE_DUMP_GPU 431 void onDumpJSON(SkJSONWriter*) const override; 432 #endif 433 434 bool createCopyProgram(GrTexture* srcTexture); 435 bool createMipmapProgram(int progIdx); 436 437 std::unique_ptr<GrGLContext> fGLContext; 438 439 // GL program-related state 440 std::unique_ptr<ProgramCache> fProgramCache; 441 442 /////////////////////////////////////////////////////////////////////////// 443 ///@name Caching of GL State 444 ///@{ 445 int fHWActiveTextureUnitIdx; 446 447 GrGLuint fHWProgramID; 448 sk_sp<GrGLProgram> fHWProgram; 449 450 enum TriState { 451 kNo_TriState, 452 kYes_TriState, 453 kUnknown_TriState 454 }; 455 456 GrGLuint fTempSrcFBOID; 457 GrGLuint fTempDstFBOID; 458 459 GrGLuint fStencilClearFBOID; 460 461 // last scissor / viewport scissor state seen by the GL. 462 struct { 463 TriState fEnabled; 464 GrNativeRect fRect; invalidate__anon53b114d50108465 void invalidate() { 466 fEnabled = kUnknown_TriState; 467 fRect.invalidate(); 468 } 469 } fHWScissorSettings; 470 471 class { 472 public: valid()473 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } invalidate()474 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } knownDisabled()475 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } setDisabled()476 void setDisabled() { 477 fRTOrigin = kTopLeft_GrSurfaceOrigin; 478 fWindowState.setDisabled(); 479 } 480 set(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)481 void set(GrSurfaceOrigin rtOrigin, int width, int height, 482 const GrWindowRectsState& windowState) { 483 fRTOrigin = rtOrigin; 484 fWidth = width; 485 fHeight = height; 486 fWindowState = windowState; 487 } 488 knownEqualTo(GrSurfaceOrigin rtOrigin,int width,int height,const GrWindowRectsState & windowState)489 bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height, 490 const GrWindowRectsState& windowState) const { 491 if (!this->valid()) { 492 return false; 493 } 494 if (fWindowState.numWindows() && 495 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) { 496 return false; 497 } 498 return fWindowState == windowState; 499 } 500 501 private: 502 enum { kInvalidSurfaceOrigin = -1 }; 503 504 int fRTOrigin; 505 int fWidth; 506 int fHeight; 507 GrWindowRectsState fWindowState; 508 } fHWWindowRectsState; 509 510 GrNativeRect fHWViewport; 511 512 /** 513 * Tracks vertex attrib array state. 514 */ 515 class HWVertexArrayState { 516 public: HWVertexArrayState()517 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 518 ~HWVertexArrayState()519 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 520 invalidate()521 void invalidate() { 522 fBoundVertexArrayIDIsValid = false; 523 fDefaultVertexArrayAttribState.invalidate(); 524 if (fCoreProfileVertexArray) { 525 fCoreProfileVertexArray->invalidateCachedState(); 526 } 527 } 528 notifyVertexArrayDelete(GrGLuint id)529 void notifyVertexArrayDelete(GrGLuint id) { 530 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 531 // Does implicit bind to 0 532 fBoundVertexArrayID = 0; 533 } 534 } 535 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)536 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 537 if (!gpu->glCaps().vertexArrayObjectSupport()) { 538 SkASSERT(0 == arrayID); 539 return; 540 } 541 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 542 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 543 fBoundVertexArrayIDIsValid = true; 544 fBoundVertexArrayID = arrayID; 545 } 546 } 547 548 /** 549 * Binds the vertex array that should be used for internal draws, and returns its attrib 550 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 551 * case we use a dummy array instead. 552 * 553 * If an index buffer is privided, it will be bound to the vertex array. Otherwise the 554 * index buffer binding will be left unchanged. 555 * 556 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 557 */ 558 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 559 560 private: 561 GrGLuint fBoundVertexArrayID; 562 bool fBoundVertexArrayIDIsValid; 563 564 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 565 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 566 // GrGLGpu. 567 GrGLAttribArrayState fDefaultVertexArrayAttribState; 568 569 // This is used when we're using a core profile. 570 GrGLVertexArray* fCoreProfileVertexArray; 571 } fHWVertexArrayState; 572 573 uint8_t fHWPatchVertexCount; 574 575 struct { 576 GrGLenum fGLTarget; 577 GrGpuResource::UniqueID fBoundBufferUniqueID; 578 bool fBufferZeroKnownBound; 579 invalidate__anon53b114d50308580 void invalidate() { 581 fBoundBufferUniqueID.makeInvalid(); 582 fBufferZeroKnownBound = false; 583 } 584 } fHWBufferState[kGrGpuBufferTypeCount]; 585 hwBufferState(GrGpuBufferType type)586 auto* hwBufferState(GrGpuBufferType type) { 587 unsigned typeAsUInt = static_cast<unsigned>(type); 588 SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState)); 589 return &fHWBufferState[typeAsUInt]; 590 } 591 592 struct { 593 GrBlendEquation fEquation; 594 GrBlendCoeff fSrcCoeff; 595 GrBlendCoeff fDstCoeff; 596 SkPMColor4f fConstColor; 597 bool fConstColorValid; 598 TriState fEnabled; 599 invalidate__anon53b114d50408600 void invalidate() { 601 fEquation = kIllegal_GrBlendEquation; 602 fSrcCoeff = kIllegal_GrBlendCoeff; 603 fDstCoeff = kIllegal_GrBlendCoeff; 604 fConstColorValid = false; 605 fEnabled = kUnknown_TriState; 606 } 607 } fHWBlendState; 608 609 TriState fMSAAEnabled; 610 TriState fHWConservativeRasterEnabled; 611 612 TriState fHWWireframeEnabled; 613 614 GrStencilSettings fHWStencilSettings; 615 GrSurfaceOrigin fHWStencilOrigin; 616 TriState fHWStencilTestEnabled; 617 618 TriState fHWWriteToColor; 619 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 620 TriState fHWSRGBFramebuffer; 621 622 class TextureUnitBindings { 623 public: 624 TextureUnitBindings() = default; 625 TextureUnitBindings(const TextureUnitBindings&) = delete; 626 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete; 627 628 GrGpuResource::UniqueID boundID(GrGLenum target) const; 629 bool hasBeenModified(GrGLenum target) const; 630 void setBoundID(GrGLenum target, GrGpuResource::UniqueID); 631 void invalidateForScratchUse(GrGLenum target); 632 void invalidateAllTargets(bool markUnmodified); 633 634 private: 635 struct TargetBinding { 636 GrGpuResource::UniqueID fBoundResourceID; 637 bool fHasBeenModified = false; 638 }; 639 TargetBinding fTargetBindings[3]; 640 }; 641 SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings; 642 643 GrGLfloat fHWClearColor[4]; 644 645 GrGLuint fBoundDrawFramebuffer = 0; 646 647 /** IDs for copy surface program. (3 sampler types) */ 648 struct { 649 GrGLuint fProgram = 0; 650 GrGLint fTextureUniform = 0; 651 GrGLint fTexCoordXformUniform = 0; 652 GrGLint fPosXformUniform = 0; 653 } fCopyPrograms[3]; 654 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 655 656 /** IDs for texture mipmap program. (4 filter configurations) */ 657 struct { 658 GrGLuint fProgram = 0; 659 GrGLint fTextureUniform = 0; 660 GrGLint fTexCoordXformUniform = 0; 661 } fMipmapPrograms[4]; 662 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 663 664 static int TextureToCopyProgramIdx(GrTexture* texture); 665 TextureSizeToMipmapProgramIdx(int width,int height)666 static int TextureSizeToMipmapProgramIdx(int width, int height) { 667 const bool wide = (width > 1) && SkToBool(width & 0x1); 668 const bool tall = (height > 1) && SkToBool(height & 0x1); 669 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 670 } 671 672 GrPrimitiveType fLastPrimitiveType; 673 674 GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0; 675 676 class SamplerObjectCache; 677 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache; 678 679 std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass; 680 681 struct FinishCallback { 682 GrGpuFinishedProc fCallback; 683 GrGpuFinishedContext fContext; 684 GrGLsync fSync; 685 }; 686 std::list<FinishCallback> fFinishCallbacks; 687 688 SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false); 689 690 friend class GrGLPathRendering; // For accessing setTextureUnit. 691 692 typedef GrGpu INHERITED; 693 }; 694 695 #endif 696