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