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

source code of flutter_engine/third_party/skia/src/gpu/ganesh/gl/GrGLGpu.h