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 "GrGLContext.h" 12 #include "GrGLIRect.h" 13 #include "GrGLPathRendering.h" 14 #include "GrGLProgram.h" 15 #include "GrGLRenderTarget.h" 16 #include "GrGLStencilAttachment.h" 17 #include "GrGLTexture.h" 18 #include "GrGLVertexArray.h" 19 #include "GrGpu.h" 20 #include "GrMesh.h" 21 #include "GrWindowRectsState.h" 22 #include "GrXferProcessor.h" 23 #include "SkLRUCache.h" 24 #include "SkTArray.h" 25 #include "SkTypes.h" 26 27 class GrGLBuffer; 28 class GrGLGpuRTCommandBuffer; 29 class GrGLGpuTextureCommandBuffer; 30 class GrPipeline; 31 class GrSwizzle; 32 33 #ifdef SK_DEBUG 34 #define PROGRAM_CACHE_STATS 35 #endif 36 37 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl { 38 public: 39 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*); 40 ~GrGLGpu() override; 41 42 void disconnect(DisconnectType) override; 43 glContext()44 const GrGLContext& glContext() const { return *fGLContext; } 45 glInterface()46 const GrGLInterface* glInterface() const { return fGLContext->interface(); } ctxInfo()47 const GrGLContextInfo& ctxInfo() const { return *fGLContext; } glStandard()48 GrGLStandard glStandard() const { return fGLContext->standard(); } glVersion()49 GrGLVersion glVersion() const { return fGLContext->version(); } glslGeneration()50 GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); } glCaps()51 const GrGLCaps& glCaps() const { return *fGLContext->caps(); } 52 glPathRendering()53 GrGLPathRendering* glPathRendering() { 54 SkASSERT(glCaps().shaderCaps()->pathRenderingSupport()); 55 return static_cast<GrGLPathRendering*>(pathRendering()); 56 } 57 58 // Used by GrGLProgram to configure OpenGL state. 59 void bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture* texture); 60 61 // These functions should be used to bind GL objects. They track the GL state and skip redundant 62 // bindings. Making the equivalent glBind calls directly will confuse the state tracking. bindVertexArray(GrGLuint id)63 void bindVertexArray(GrGLuint id) { 64 fHWVertexArrayState.setVertexArrayID(this, id); 65 } 66 67 // These callbacks update state tracking when GL objects are deleted. They are called from 68 // GrGLResource onRelease functions. notifyVertexArrayDelete(GrGLuint id)69 void notifyVertexArrayDelete(GrGLuint id) { 70 fHWVertexArrayState.notifyVertexArrayDelete(id); 71 } 72 73 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and 74 // returns the GL target the buffer was bound to. 75 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. 76 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. 77 GrGLenum bindBuffer(GrBufferType type, const GrBuffer*); 78 79 // The GrGLGpuRTCommandBuffer 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 GrGLRTGpuCommandBuffer. 82 void draw(GrRenderTarget*, GrSurfaceOrigin, 83 const GrPrimitiveProcessor&, 84 const GrPipeline&, 85 const GrPipeline::FixedDynamicState*, 86 const GrPipeline::DynamicStateArrays*, 87 const GrMesh[], 88 int meshCount); 89 90 // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls. 91 // Marked final as a hint to the compiler to not use virtual dispatch. 92 void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, 93 int baseVertex) final; 94 95 void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, 96 int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue, 97 const GrBuffer* vertexBuffer, int baseVertex, 98 GrPrimitiveRestart) final; 99 100 void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount, 101 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount, 102 int baseInstance) final; 103 104 void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount, 105 int baseIndex, const GrBuffer* vertexBuffer, int baseVertex, 106 const GrBuffer* instanceBuffer, int instanceCount, 107 int baseInstance, GrPrimitiveRestart) final; 108 109 // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. 110 // Thus this is the implementation of the clear call for the corresponding passthrough function 111 // on GrGLGpuRTCommandBuffer. 112 void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin); 113 114 // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu. 115 // Thus this is the implementation of the clearStencil call for the corresponding passthrough 116 // function on GrGLGpuRTCommandBuffer. 117 void clearStencilClip(const GrFixedClip&, bool insideStencilMask, 118 GrRenderTarget*, GrSurfaceOrigin); 119 120 // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the 121 // stencil buffer as not dirty? 122 void clearStencil(GrRenderTarget*, int clearValue); 123 124 GrGpuRTCommandBuffer* getCommandBuffer( 125 GrRenderTarget*, GrSurfaceOrigin, const SkRect&, 126 const GrGpuRTCommandBuffer::LoadAndStoreInfo&, 127 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override; 128 129 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override; 130 invalidateBoundRenderTarget()131 void invalidateBoundRenderTarget() { 132 fHWBoundRenderTargetUniqueID.makeInvalid(); 133 } 134 135 GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt, 136 int width, 137 int height) override; 138 #if GR_TEST_UTILS 139 GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h, 140 GrColorType colorType, bool isRenderTarget, 141 GrMipMapped mipMapped, 142 size_t rowBytes = 0) override; 143 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 144 void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override; 145 146 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override; 147 148 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 149 glContextForTesting()150 const GrGLContext* glContextForTesting() const override { return &this->glContext(); } 151 resetShaderCacheForTesting()152 void resetShaderCacheForTesting() const override { fProgramCache->abandon(); } 153 154 void testingOnly_flushGpuAndSync() override; 155 #endif 156 157 void submit(GrGpuCommandBuffer* buffer) override; 158 159 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 160 bool waitFence(GrFence, uint64_t timeout) override; 161 void deleteFence(GrFence) const override; 162 163 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override; 164 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore, 165 GrResourceProvider::SemaphoreWrapType wrapType, 166 GrWrapOwnership ownership) override; 167 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override; 168 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override; 169 170 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 171 172 void deleteSync(GrGLsync) const; 173 174 void insertEventMarker(const char*); 175 176 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid); 177 void deleteFramebuffer(GrGLuint fboid); 178 179 private: 180 GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*); 181 182 // GrGpu overrides 183 void onResetContext(uint32_t resetBits) override; 184 185 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override; 186 187 sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 188 const GrMipLevel texels[], int mipLevelCount) override; 189 190 sk_sp<GrBuffer> onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, 191 const void* data) override; 192 193 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable, 194 GrIOType) override; 195 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt, 196 GrWrapOwnership, GrWrapCacheable) override; 197 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override; 198 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, 199 int sampleCnt) override; 200 201 // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a 202 // compatible stencil format, or negative if there is no compatible stencil format. 203 int getCompatibleStencilIndex(GrPixelConfig config); 204 205 void onFBOChanged(); 206 207 // Returns whether the texture is successfully created. On success, the 208 // result is stored in |info|. 209 // The texture is populated with |texels|, if it exists. 210 // The texture parameters are cached in |initialTexParams|. 211 bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget, 212 GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[], 213 int mipLevelCount, GrMipMapsStatus* mipMapsStatus); 214 215 // Checks whether glReadPixels can be called to get pixel values in readConfig from the 216 // render target. 217 bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig); 218 219 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 220 // render target that has renderTargetConfig. This may have to create a temporary 221 // render target and thus is less preferable than the variant that takes a render target. 222 bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig); 223 224 // Checks whether glReadPixels can be called to get pixel values in readConfig from a 225 // render target that has the same config as surfaceForConfig. Calls one of the the two 226 // variations above, depending on whether the surface is a render target or not. 227 bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig); 228 229 bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType, 230 void* buffer, size_t rowBytes) override; 231 232 bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType, 233 const GrMipLevel texels[], int mipLevelCount) override; 234 235 bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrColorType, 236 GrBuffer* transferBuffer, size_t offset, size_t rowBytes) override; 237 238 // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the 239 // PIXEL_UNPACK_BUFFER is unbound. 240 void unbindCpuToGpuXferBuffer(); 241 242 void onResolveRenderTarget(GrRenderTarget* target) override; 243 244 bool onRegenerateMipMapLevels(GrTexture*) override; 245 246 bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, 247 GrSurface* src, GrSurfaceOrigin srcOrigin, 248 const SkIRect& srcRect, const SkIPoint& dstPoint, 249 bool canDiscardOutsideDstRect) override; 250 251 // binds texture unit in GL 252 void setTextureUnit(int unitIdx); 253 254 /** 255 * primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() * 256 * numPrimitiveProcessorTextureSets entries. 257 */ 258 void resolveAndGenerateMipMapsForProcessorTextures( 259 const GrPrimitiveProcessor&, const GrPipeline&, 260 const GrTextureProxy* const primitiveProcessorTextures[], 261 int numPrimitiveProcessorTextureSets); 262 263 // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. 264 // willDrawPoints must be true if point primitives will be rendered after setting the GL state. 265 // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic 266 // state entries in each array. 267 bool flushGLState(GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&, 268 const GrPipeline&, const GrPipeline::FixedDynamicState*, 269 const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength, 270 bool willDrawPoints); 271 272 void flushProgram(sk_sp<GrGLProgram>); 273 274 // Version for programs that aren't GrGLProgram. 275 void flushProgram(GrGLuint); 276 277 // Sets up vertex/instance attribute pointers and strides. 278 void setupGeometry(const GrBuffer* indexBuffer, 279 const GrBuffer* vertexBuffer, 280 int baseVertex, 281 const GrBuffer* instanceBuffer, 282 int baseInstance, 283 GrPrimitiveRestart); 284 285 void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&); 286 287 void onFinishFlush(bool insertedSemaphores) override; 288 289 bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin, 290 GrSurface* src, GrSurfaceOrigin srcOrigin, 291 const SkIRect& srcRect, const SkIPoint& dstPoint); 292 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin, 293 GrSurface* src, GrSurfaceOrigin srcOrigin, 294 const SkIRect& srcRect, const SkIPoint& dstPoint); 295 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin, 296 GrSurface* src, GrSurfaceOrigin srcOrigin, 297 const SkIRect& srcRect, const SkIPoint& dstPoint); 298 299 static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff); 300 301 class ProgramCache : public ::SkNoncopyable { 302 public: 303 ProgramCache(GrGLGpu* gpu); 304 ~ProgramCache(); 305 306 void abandon(); 307 GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin, 308 const GrPrimitiveProcessor&, 309 const GrTextureProxy* const primProcProxies[], 310 const GrPipeline&, bool hasPointSize); 311 312 private: 313 // We may actually have kMaxEntries+1 shaders in the GL context because we create a new 314 // shader before evicting from the cache. 315 static const int kMaxEntries = 128; 316 317 struct Entry; 318 319 // binary search for entry matching desc. returns index into fEntries that matches desc or ~ 320 // of the index of where it should be inserted. 321 int search(const GrProgramDesc& desc) const; 322 323 struct DescHash { operatorDescHash324 uint32_t operator()(const GrProgramDesc& desc) const { 325 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0); 326 } 327 }; 328 329 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap; 330 331 GrGLGpu* fGpu; 332 #ifdef PROGRAM_CACHE_STATS 333 int fTotalRequests; 334 int fCacheMisses; 335 int fHashMisses; // cache hit but hash table missed 336 #endif 337 }; 338 339 void flushColorWrite(bool writeColor); 340 void flushClearColor(GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a); 341 342 // flushes the scissor. see the note on flushBoundTextureAndParams about 343 // flushing the scissor after that function is called. 344 void flushScissor(const GrScissorState&, 345 const GrGLIRect& rtViewport, 346 GrSurfaceOrigin rtOrigin); 347 348 // disables the scissor 349 void disableScissor(); 350 351 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin); 352 void disableWindowRectangles(); 353 354 // sets a texture unit to use for texture operations other than binding a texture to a program. 355 // ensures that such operations don't negatively interact with tracking bound textures. 356 void setScratchTextureUnit(); 357 358 // The passed bounds contains the render target's color values that will subsequently be 359 // written. 360 void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds); 361 // This version has an implicit bounds of the entire render target. 362 void flushRenderTarget(GrGLRenderTarget*); 363 // This version can be used when the render target's colors will not be written. 364 void flushRenderTargetNoColorWrites(GrGLRenderTarget*); 365 366 // Need not be called if flushRenderTarget is used. 367 void flushViewport(const GrGLIRect&); 368 369 void flushStencil(const GrStencilSettings&); 370 void disableStencil(); 371 372 // rt is used only if useHWAA is true. 373 void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled); 374 375 void flushFramebufferSRGB(bool enable); 376 377 // helper for onCreateTexture and writeTexturePixels 378 enum UploadType { 379 kNewTexture_UploadType, // we are creating a new texture 380 kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture 381 }; 382 bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, GrGLenum target, 383 UploadType uploadType, int left, int top, int width, int height, 384 GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount, 385 GrMipMapsStatus* mipMapsStatus = nullptr); 386 387 // helper for onCreateCompressedTexture. Compressed textures are read-only so we 388 // only use this to populate a new texture. 389 bool uploadCompressedTexData(GrPixelConfig texConfig, int texWidth, int texHeight, 390 GrGLenum target, GrPixelConfig dataConfig, 391 const GrMipLevel texels[], int mipLevelCount, 392 GrMipMapsStatus* mipMapsStatus = nullptr); 393 394 bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo, 395 GrGLRenderTarget::IDDesc*); 396 397 enum TempFBOTarget { 398 kSrc_TempFBOTarget, 399 kDst_TempFBOTarget 400 }; 401 402 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an 403 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO 404 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps(). 405 void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport, 406 TempFBOTarget tempFBOTarget); 407 408 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying. 409 void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface); 410 411 #ifdef SK_ENABLE_DUMP_GPU 412 void onDumpJSON(SkJSONWriter*) const override; 413 #endif 414 415 bool createCopyProgram(GrTexture* srcTexture); 416 bool createMipmapProgram(int progIdx); 417 418 std::unique_ptr<GrGLContext> fGLContext; 419 420 // GL program-related state 421 ProgramCache* fProgramCache; 422 423 /////////////////////////////////////////////////////////////////////////// 424 ///@name Caching of GL State 425 ///@{ 426 int fHWActiveTextureUnitIdx; 427 428 GrGLuint fHWProgramID; 429 sk_sp<GrGLProgram> fHWProgram; 430 431 enum TriState { 432 kNo_TriState, 433 kYes_TriState, 434 kUnknown_TriState 435 }; 436 437 GrGLuint fTempSrcFBOID; 438 GrGLuint fTempDstFBOID; 439 440 GrGLuint fStencilClearFBOID; 441 442 // last scissor / viewport scissor state seen by the GL. 443 struct { 444 TriState fEnabled; 445 GrGLIRect fRect; invalidate__anon4d766a4c0108446 void invalidate() { 447 fEnabled = kUnknown_TriState; 448 fRect.invalidate(); 449 } 450 } fHWScissorSettings; 451 452 class { 453 public: valid()454 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; } invalidate()455 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; } knownDisabled()456 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); } setDisabled()457 void setDisabled() { 458 fRTOrigin = kTopLeft_GrSurfaceOrigin; 459 fWindowState.setDisabled(); 460 } 461 set(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)462 void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 463 const GrWindowRectsState& windowState) { 464 fRTOrigin = rtOrigin; 465 fViewport = viewport; 466 fWindowState = windowState; 467 } 468 knownEqualTo(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)469 bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport, 470 const GrWindowRectsState& windowState) const { 471 if (!this->valid()) { 472 return false; 473 } 474 if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) { 475 return false; 476 } 477 return fWindowState == windowState; 478 } 479 480 private: 481 enum { kInvalidSurfaceOrigin = -1 }; 482 483 int fRTOrigin; 484 GrGLIRect fViewport; 485 GrWindowRectsState fWindowState; 486 } fHWWindowRectsState; 487 488 GrGLIRect fHWViewport; 489 490 /** 491 * Tracks vertex attrib array state. 492 */ 493 class HWVertexArrayState { 494 public: HWVertexArrayState()495 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); } 496 ~HWVertexArrayState()497 ~HWVertexArrayState() { delete fCoreProfileVertexArray; } 498 invalidate()499 void invalidate() { 500 fBoundVertexArrayIDIsValid = false; 501 fDefaultVertexArrayAttribState.invalidate(); 502 if (fCoreProfileVertexArray) { 503 fCoreProfileVertexArray->invalidateCachedState(); 504 } 505 } 506 notifyVertexArrayDelete(GrGLuint id)507 void notifyVertexArrayDelete(GrGLuint id) { 508 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) { 509 // Does implicit bind to 0 510 fBoundVertexArrayID = 0; 511 } 512 } 513 setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)514 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) { 515 if (!gpu->glCaps().vertexArrayObjectSupport()) { 516 SkASSERT(0 == arrayID); 517 return; 518 } 519 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) { 520 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID)); 521 fBoundVertexArrayIDIsValid = true; 522 fBoundVertexArrayID = arrayID; 523 } 524 } 525 526 /** 527 * Binds the vertex array that should be used for internal draws, and returns its attrib 528 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which 529 * case we use a dummy array instead. 530 * 531 * If an index buffer is privided, it will be bound to the vertex array. Otherwise the 532 * index buffer binding will be left unchanged. 533 * 534 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. 535 */ 536 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); 537 538 private: 539 GrGLuint fBoundVertexArrayID; 540 bool fBoundVertexArrayIDIsValid; 541 542 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0 543 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of 544 // GrGLGpu. 545 GrGLAttribArrayState fDefaultVertexArrayAttribState; 546 547 // This is used when we're using a core profile. 548 GrGLVertexArray* fCoreProfileVertexArray; 549 } fHWVertexArrayState; 550 551 struct { 552 GrGLenum fGLTarget; 553 GrGpuResource::UniqueID fBoundBufferUniqueID; 554 bool fBufferZeroKnownBound; 555 invalidate__anon4d766a4c0308556 void invalidate() { 557 fBoundBufferUniqueID.makeInvalid(); 558 fBufferZeroKnownBound = false; 559 } 560 } fHWBufferState[kGrBufferTypeCount]; 561 562 struct { 563 GrBlendEquation fEquation; 564 GrBlendCoeff fSrcCoeff; 565 GrBlendCoeff fDstCoeff; 566 SkPMColor4f fConstColor; 567 bool fConstColorValid; 568 TriState fEnabled; 569 invalidate__anon4d766a4c0408570 void invalidate() { 571 fEquation = kIllegal_GrBlendEquation; 572 fSrcCoeff = kIllegal_GrBlendCoeff; 573 fDstCoeff = kIllegal_GrBlendCoeff; 574 fConstColorValid = false; 575 fEnabled = kUnknown_TriState; 576 } 577 } fHWBlendState; 578 579 TriState fMSAAEnabled; 580 581 GrStencilSettings fHWStencilSettings; 582 TriState fHWStencilTestEnabled; 583 584 585 TriState fHWWriteToColor; 586 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID; 587 TriState fHWSRGBFramebuffer; 588 SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs; 589 590 GrGLfloat fHWClearColor[4]; 591 592 GrGLuint fBoundDrawFramebuffer = 0; 593 594 // EXT_raster_multisample. 595 TriState fHWRasterMultisampleEnabled; 596 int fHWNumRasterSamples; 597 ///@} 598 599 /** IDs for copy surface program. (3 sampler types) */ 600 struct { 601 GrGLuint fProgram = 0; 602 GrGLint fTextureUniform = 0; 603 GrGLint fTexCoordXformUniform = 0; 604 GrGLint fPosXformUniform = 0; 605 } fCopyPrograms[3]; 606 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer; 607 608 /** IDs for texture mipmap program. (4 filter configurations) */ 609 struct { 610 GrGLuint fProgram = 0; 611 GrGLint fTextureUniform = 0; 612 GrGLint fTexCoordXformUniform = 0; 613 } fMipmapPrograms[4]; 614 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer; 615 616 static int TextureToCopyProgramIdx(GrTexture* texture); 617 TextureSizeToMipmapProgramIdx(int width,int height)618 static int TextureSizeToMipmapProgramIdx(int width, int height) { 619 const bool wide = (width > 1) && SkToBool(width & 0x1); 620 const bool tall = (height > 1) && SkToBool(height & 0x1); 621 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0); 622 } 623 624 GrPrimitiveType fLastPrimitiveType; 625 626 class SamplerObjectCache; 627 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache; 628 629 std::unique_ptr<GrGLGpuRTCommandBuffer> fCachedRTCommandBuffer; 630 std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer; 631 632 friend class GrGLPathRendering; // For accessing setTextureUnit. 633 634 typedef GrGpu INHERITED; 635 }; 636 637 #endif 638