blob: 0652fa67acaaa67d512a3cec7be8b6e9b9f4607c [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
jvanverth39edf762014-12-22 11:44:19 -08008#ifndef GrGLGpu_DEFINED
9#define GrGLGpu_DEFINED
reed@google.comac10a2d2010-12-22 21:39:39 +000010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTypes.h"
12#include "include/private/SkTArray.h"
13#include "src/core/SkLRUCache.h"
Stephen Whiteb353c9b2020-04-16 14:14:13 -040014#include "src/gpu/GrFinishCallbacks.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrGpu.h"
Chris Daltond6cda8d2019-09-05 02:30:04 -060016#include "src/gpu/GrNativeRect.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050017#include "src/gpu/GrProgramDesc.h"
Robert Phillipsae67c522021-03-03 11:03:38 -050018#include "src/gpu/GrThreadSafePipelineBuilder.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "src/gpu/GrWindowRectsState.h"
20#include "src/gpu/GrXferProcessor.h"
Greg Danielc0d69152020-10-08 14:59:00 -040021#include "src/gpu/gl/GrGLAttachment.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/gpu/gl/GrGLContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/gl/GrGLProgram.h"
24#include "src/gpu/gl/GrGLRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/gl/GrGLTexture.h"
26#include "src/gpu/gl/GrGLVertexArray.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000027
cdalton397536c2016-03-25 12:15:03 -070028class GrGLBuffer;
Greg Daniel2d41d0d2019-08-26 11:08:51 -040029class GrGLOpsRenderPass;
egdaniel8dd688b2015-01-22 10:16:09 -080030class GrPipeline;
bsalomon7f9b2e42016-01-12 13:29:26 -080031class GrSwizzle;
egdaniel8dd688b2015-01-22 10:16:09 -080032
Chris Dalton33db9fc2020-02-25 18:52:12 -070033class GrGLGpu final : public GrGpu {
reed@google.comac10a2d2010-12-22 21:39:39 +000034public:
Adlai Holler3d0359a2020-07-09 15:35:55 -040035 static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrDirectContext*);
mtklein36352bf2015-03-25 18:17:31 -070036 ~GrGLGpu() override;
reed@google.comac10a2d2010-12-22 21:39:39 +000037
bsalomon6e2aad42016-04-01 11:54:31 -070038 void disconnect(DisconnectType) override;
bsalomonc8dc1f72014-08-21 13:02:13 -070039
Robert Phillipsae67c522021-03-03 11:03:38 -050040 GrThreadSafePipelineBuilder* pipelineBuilder() override;
41 sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override;
42
bsalomon424cc262015-05-22 10:37:30 -070043 const GrGLContext& glContext() const { return *fGLContext; }
commit-bot@chromium.orgc9424b82013-10-30 20:03:16 +000044
Jim Van Verth03b8ab22020-02-24 11:36:15 -050045 const GrGLInterface* glInterface() const { return fGLContext->glInterface(); }
bsalomon424cc262015-05-22 10:37:30 -070046 const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
47 GrGLStandard glStandard() const { return fGLContext->standard(); }
48 GrGLVersion glVersion() const { return fGLContext->version(); }
Jim Van Verthd8a753a2021-11-17 17:34:43 -050049 SkSL::GLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
bsalomon424cc262015-05-22 10:37:30 -070050 const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
bsalomon@google.com0b77d682011-08-19 13:28:54 +000051
kkinnunencfe62e32015-07-01 02:58:50 -070052 // Used by GrGLProgram to configure OpenGL state.
Greg Daniel2c3398d2019-06-19 11:58:01 -040053 void bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwizzle&, GrGLTexture*);
kkinnunenccdaa042014-08-20 01:36:23 -070054
bsalomon@google.com6918d482013-03-07 19:09:11 +000055 // These functions should be used to bind GL objects. They track the GL state and skip redundant
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +000056 // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bsalomon@google.com6918d482013-03-07 19:09:11 +000057 void bindVertexArray(GrGLuint id) {
cdaltone2e71c22016-04-07 18:13:29 -070058 fHWVertexArrayState.setVertexArrayID(this, id);
bsalomon@google.com6918d482013-03-07 19:09:11 +000059 }
60
61 // These callbacks update state tracking when GL objects are deleted. They are called from
62 // GrGLResource onRelease functions.
63 void notifyVertexArrayDelete(GrGLuint id) {
cdaltone2e71c22016-04-07 18:13:29 -070064 fHWVertexArrayState.notifyVertexArrayDelete(id);
bsalomon@google.com6918d482013-03-07 19:09:11 +000065 }
bsalomon@google.com880b8fc2013-02-19 20:17:28 +000066
cdaltone2e71c22016-04-07 18:13:29 -070067 // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
68 // returns the GL target the buffer was bound to.
69 // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
70 // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
Brian Salomonae64c192019-02-05 09:41:37 -050071 GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer*);
joshualitt93316b92015-10-23 09:08:08 -070072
Chris Dalton20e7a532020-02-28 15:37:53 +000073 // Flushes state from GrProgramInfo to GL. Returns false if the state couldn't be set.
Chris Daltonb0fed1d2021-04-07 21:12:22 -060074 bool flushGLState(GrRenderTarget*, bool useMultisampleFBO, const GrProgramInfo&);
Robert Phillipsedc5b4d2021-01-06 13:06:23 -050075 void flushScissorRect(const SkIRect& scissor, int rtHeight, GrSurfaceOrigin);
76
77 // The flushRenderTarget methods will all set the initial viewport to the full extent of the
78 // backing render target.
79 void flushViewport(const SkIRect& viewport, int rtHeight, GrSurfaceOrigin);
Chris Daltond42d2002020-02-28 12:05:04 -070080
81 // Returns the last program bound by flushGLState(), or nullptr if a different program has since
82 // been put into use via some other method (e.g., resetContext, copySurfaceAsDraw).
83 // The returned GrGLProgram can be used for binding textures and vertex attributes.
84 GrGLProgram* currentProgram() {
85 this->handleDirtyContext();
86 return fHWProgram.get();
Chris Daltonb67081f2020-02-27 15:13:56 -070087 }
Chris Daltonb67081f2020-02-27 15:13:56 -070088
Chris Daltond42d2002020-02-28 12:05:04 -070089 // Binds the vertex array that should be used for internal draws, enables 'numAttribs' vertex
90 // arrays, and flushes the desired primitive restart settings. If an index buffer is provided,
91 // it will be bound to the vertex array. Otherwise the index buffer binding will be left
92 // unchanged.
93 //
94 // NOTE: This binds the default VAO (ID=zero) unless we are on a core profile, in which case we
Kevin Lubickbe03ef12021-06-16 15:28:00 -040095 // use a placeholder array instead.
Chris Daltond42d2002020-02-28 12:05:04 -070096 GrGLAttribArrayState* bindInternalVertexArray(const GrBuffer* indexBuffer, int numAttribs,
97 GrPrimitiveRestart primitiveRestart) {
98 auto* attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
99 attribState->enableVertexArrays(this, numAttribs, primitiveRestart);
100 return attribState;
101 }
Chris Daltond42d2002020-02-28 12:05:04 -0700102
Chris Dalton0999bce2020-04-03 14:42:05 -0600103 // Applies any necessary workarounds and returns the GL primitive type to use in draw calls.
104 GrGLenum prepareToDraw(GrPrimitiveType primitiveType);
Chris Dalton1d616352017-05-31 12:51:23 -0600105
Brian Salomon4b4c7f82021-09-23 10:30:55 -0400106 using ResolveDirection = GrGLRenderTarget::ResolveDirection;
Chris Dalton710e1c92021-04-23 13:07:52 -0600107
Chris Dalton88dd3562021-07-20 11:32:58 -0600108 // Resolves the render target's single sample FBO into the MSAA, or vice versa.
109 // If glCaps.framebufferResolvesMustBeFullSize() is true, resolveRect must be equal the render
110 // target's bounds rect.
111 // If blitting single to MSAA, glCaps.canResolveSingleToMSAA() must be true.
Chris Dalton710e1c92021-04-23 13:07:52 -0600112 void resolveRenderFBOs(GrGLRenderTarget*, const SkIRect& resolveRect, ResolveDirection,
113 bool invalidateReadBufferAfterBlit = false);
114
Chris Dalton88dd3562021-07-20 11:32:58 -0600115 // For loading a dynamic MSAA framebuffer when glCaps.canResolveSingleToMSAA() is false.
116 // NOTE: If glCaps.framebufferResolvesMustBeFullSize() is also true, the drawBounds should be
117 // equal to the proxy bounds. This is because the render pass will have to do a full size
118 // resolve back into the single sample FBO when rendering is complete.
119 void drawSingleIntoMSAAFBO(GrGLRenderTarget* rt, const SkIRect& drawBounds) {
120 this->copySurfaceAsDraw(rt, true/*drawToMultisampleFBO*/, rt, drawBounds,
121 drawBounds.topLeft());
122 }
123
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400124 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
egdaniel9cb63402016-06-23 08:37:05 -0700125 // Thus this is the implementation of the clear call for the corresponding passthrough function
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400126 // on GrGLOpsRenderPass.
Chris Daltonb0fed1d2021-04-07 21:12:22 -0600127 void clear(const GrScissorState&, std::array<float, 4> color, GrRenderTarget*,
128 bool useMultisampleFBO, GrSurfaceOrigin);
egdaniel9cb63402016-06-23 08:37:05 -0700129
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400130 // The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
egdaniel9cb63402016-06-23 08:37:05 -0700131 // Thus this is the implementation of the clearStencil call for the corresponding passthrough
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400132 // function on GrGLOpsrenderPass.
Michael Ludwig1e632792020-05-21 12:45:31 -0400133 void clearStencilClip(const GrScissorState&, bool insideStencilMask,
Chris Daltone0fe23a2021-04-23 13:11:44 -0600134 GrRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin);
egdaniel9cb63402016-06-23 08:37:05 -0700135
Chris Dalton710e1c92021-04-23 13:07:52 -0600136 void beginCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO,
Chris Daltonb0fed1d2021-04-07 21:12:22 -0600137 const SkIRect& bounds, GrSurfaceOrigin,
Chris Dalton674f77a2019-09-30 20:49:39 -0600138 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
139 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
140
Chris Dalton710e1c92021-04-23 13:07:52 -0600141 void endCommandBuffer(GrGLRenderTarget*, bool useMultisampleFBO,
Chris Daltonb0fed1d2021-04-07 21:12:22 -0600142 const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
Chris Dalton674f77a2019-09-30 20:49:39 -0600143 const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);
144
egdanielec00d942015-09-14 12:56:10 -0700145 void invalidateBoundRenderTarget() {
Robert Phillips294870f2016-11-11 12:38:40 -0500146 fHWBoundRenderTargetUniqueID.makeInvalid();
egdanielec00d942015-09-14 12:56:10 -0700147 }
148
Chris Daltone0fe23a2021-04-23 13:11:44 -0600149 sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& colorFormat,
150 SkISize dimensions, int numStencilSamples) override;
Greg Daniel5d0330e2020-10-12 16:05:21 -0400151
152 sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
153 const GrBackendFormat& format,
154 int numSamples,
Jim Van Verth8d59fe02021-09-20 11:48:21 -0400155 GrProtected isProtected,
156 GrMemoryless) override;
Greg Daniel5d0330e2020-10-12 16:05:21 -0400157
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400158 void deleteBackendTexture(const GrBackendTexture&) override;
jvanverth672bb7f2015-07-13 07:19:57 -0700159
Robert Phillips3bce1f72020-05-12 12:41:58 -0400160 bool compile(const GrProgramDesc&, const GrProgramInfo&) override;
Robert Phillips979b2232020-02-20 10:47:29 -0500161
Brian Osmaned58e002019-09-06 14:42:43 -0400162 bool precompileShader(const SkData& key, const SkData& data) override {
Robert Phillips962708f2021-03-03 14:42:04 -0500163 return fProgramCache->precompileShader(this->getContext(), key, data);
Brian Osmaned58e002019-09-06 14:42:43 -0400164 }
165
Robert Phillipsf0ced622019-05-16 09:06:25 -0400166#if GR_TEST_UTILS
167 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
Michael Ludwig8ad0cbd2019-05-15 19:32:01 +0000168
Brian Salomonf9b00422020-10-08 16:00:14 -0400169 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions,
Brian Salomon72c7b982020-10-06 10:07:38 -0400170 GrColorType,
Brian Salomonf9b00422020-10-08 16:00:14 -0400171 int sampleCnt,
172 GrProtected) override;
Brian Salomonf865b052018-03-09 09:01:53 -0500173 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
174
175 const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
176
Brian Osman0b8bb882019-04-12 11:47:19 -0400177 void resetShaderCacheForTesting() const override { fProgramCache->reset(); }
Brian Salomonf865b052018-03-09 09:01:53 -0500178#endif
Greg Daniel26b50a42018-03-08 09:49:58 -0500179
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400180 void submit(GrOpsRenderPass* renderPass) override;
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400181
Greg Daniel6be35232017-03-01 17:01:09 -0500182 GrFence SK_WARN_UNUSED_RESULT insertFence() override;
Stephen Whiteb353c9b2020-04-16 14:14:13 -0400183 bool waitFence(GrFence) override;
jvanverth84741b32016-09-30 08:39:02 -0700184 void deleteFence(GrFence) const override;
185
Greg Daniel301015c2019-11-18 14:06:46 -0500186 std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
Robert Phillips1a82a4e2021-07-01 10:27:44 -0400187 std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
188 GrSemaphoreWrapType,
189 GrWrapOwnership) override;
Greg Daniel301015c2019-11-18 14:06:46 -0500190 void insertSemaphore(GrSemaphore* semaphore) override;
191 void waitSemaphore(GrSemaphore* semaphore) override;
Greg Daniel6be35232017-03-01 17:01:09 -0500192
Brian Salomonb0d8b762019-05-06 16:58:22 -0400193 void checkFinishProcs() override;
Greg Daniela89b4302021-01-29 10:48:40 -0500194 void finishOutstandingGpuWork() override;
Brian Salomonb0d8b762019-05-06 16:58:22 -0400195
Brian Salomon24069eb2020-06-24 10:19:52 -0400196 // Calls glGetError() until no errors are reported. Also looks for OOMs.
197 void clearErrorsAndCheckForOOM();
198 // Calls glGetError() once and returns the result. Also looks for an OOM.
199 GrGLenum getErrorAndCheckForOOM();
200
Greg Daniel301015c2019-11-18 14:06:46 -0500201 std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
Brian Osman13dddce2017-05-09 13:19:50 -0400202
Greg Daniel6be35232017-03-01 17:01:09 -0500203 void deleteSync(GrGLsync) const;
204
Adrienne Walker4ee88512018-05-17 11:37:14 -0700205 void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
206 void deleteFramebuffer(GrGLuint fboid);
Adrienne Walker3ed33992018-05-15 11:44:34 -0700207
Chris Daltone1196c52019-12-28 14:31:09 -0700208 void insertManualFramebufferBarrier() override;
209
Robert Phillipsdf546db2020-05-29 09:42:54 -0400210 void flushProgram(sk_sp<GrGLProgram>);
211
212 // Version for programs that aren't GrGLProgram.
213 void flushProgram(GrGLuint);
214
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000215private:
Adlai Holler3d0359a2020-07-09 15:35:55 -0400216 GrGLGpu(std::unique_ptr<GrGLContext>, GrDirectContext*);
bsalomon424cc262015-05-22 10:37:30 -0700217
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000218 // GrGpu overrides
Robert Phillipsb915c942019-12-17 14:44:37 -0500219 GrBackendTexture onCreateBackendTexture(SkISize dimensions,
Brian Salomon85c3d682019-11-04 15:04:54 -0500220 const GrBackendFormat&,
221 GrRenderable,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400222 GrMipmapped,
Greg Daniel16032b32020-05-06 15:31:10 -0400223 GrProtected) override;
Robert Phillips57ef6802019-09-23 10:12:47 -0400224
Robert Phillipsb915c942019-12-17 14:44:37 -0500225 GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
226 const GrBackendFormat&,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400227 GrMipmapped,
Greg Danielaaf738c2020-07-10 09:30:33 -0400228 GrProtected) override;
Robert Phillipsb915c942019-12-17 14:44:37 -0500229
Brian Salomon71283232021-04-08 12:45:58 -0400230 bool onClearBackendTexture(const GrBackendTexture&,
231 sk_sp<GrRefCntedCallback> finishedCallback,
232 std::array<float, 4> color) override;
Greg Daniel16032b32020-05-06 15:31:10 -0400233
Greg Danielaaf738c2020-07-10 09:30:33 -0400234 bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
235 sk_sp<GrRefCntedCallback> finishedCallback,
Brian Salomon71283232021-04-08 12:45:58 -0400236 const void* data,
237 size_t length) override;
Greg Danielaaf738c2020-07-10 09:30:33 -0400238
mtklein36352bf2015-03-25 18:17:31 -0700239 void onResetContext(uint32_t resetBits) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000240
Brian Salomon1f05d452019-02-08 12:33:08 -0500241 void onResetTextureBindings() override;
242
bsalomoncb02b382015-08-12 11:14:50 -0700243 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
244
Brian Salomona56a7462020-02-07 14:17:25 -0500245 sk_sp<GrTexture> onCreateTexture(SkISize dimensions,
Brian Salomon81536f22019-08-08 16:30:49 -0400246 const GrBackendFormat&,
247 GrRenderable,
248 int renderTargetSampleCnt,
249 SkBudgeted,
250 GrProtected,
Brian Salomond2a8ae22019-09-10 16:03:59 -0400251 int mipLevelCount,
252 uint32_t levelClearMask) override;
Robert Phillips9f744f72019-12-19 19:14:33 -0500253 sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
254 const GrBackendFormat&,
Robert Phillips3a833922020-01-21 15:25:58 -0500255 SkBudgeted,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400256 GrMipmapped,
Robert Phillips3a833922020-01-21 15:25:58 -0500257 GrProtected,
Robert Phillips9f744f72019-12-19 19:14:33 -0500258 const void* data, size_t dataSize) override;
cblume55f2d2d2016-02-26 13:20:48 -0800259
Brian Salomondbf70722019-02-07 11:31:24 -0500260 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern,
261 const void* data) override;
Greg Daniel7ef28f32017-04-20 16:41:55 +0000262
Brian Salomon8a78e9c2020-03-27 10:42:15 -0400263 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
264 GrWrapOwnership,
265 GrWrapCacheable,
266 GrIOType) override;
267 sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
268 GrWrapOwnership,
Robert Phillipsb915c942019-12-17 14:44:37 -0500269 GrWrapCacheable) override;
Brian Salomon8a78e9c2020-03-27 10:42:15 -0400270 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
271 int sampleCnt,
272 GrWrapOwnership,
Robert Phillips0902c982019-07-16 07:47:56 -0400273 GrWrapCacheable) override;
Brian Salomon8a78e9c2020-03-27 10:42:15 -0400274 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
csmartdaltone0d36292016-07-29 08:14:20 -0700275
Brian Salomonf6da1462019-07-11 14:21:59 -0400276 // Given a GL format return the index into the stencil format array on GrGLCaps to a
bsalomon62a627b2015-12-17 09:50:47 -0800277 // compatible stencil format, or negative if there is no compatible stencil format.
Brian Salomon5043f1f2019-07-11 21:27:54 -0400278 int getCompatibleStencilIndex(GrGLFormat format);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000279
Greg Danielb8949bd2020-10-12 15:21:02 -0400280 GrBackendFormat getPreferredStencilFormat(const GrBackendFormat& format) override {
Greg Danielb8949bd2020-10-12 15:21:02 -0400281 int idx = this->getCompatibleStencilIndex(format.asGLFormat());
282 if (idx < 0) {
283 return {};
284 }
285 return GrBackendFormat::MakeGL(GrGLFormatToEnum(this->glCaps().stencilFormats()[idx]),
286 GR_GL_TEXTURE_NONE);
287 }
288
Adrienne Walkerca0cdef2018-08-20 13:49:40 -0700289 void onFBOChanged();
bsalomon7e68ab72016-04-13 14:29:25 -0700290
Brian Salomonea4ad302019-08-07 13:04:55 -0400291 // Returns whether the texture is successfully created. On success, a non-zero texture ID is
292 // returned. On failure, zero is returned.
293 // The texture is populated with |texels|, if it is non-null.
erikchen9a1ed5d2016-02-10 16:32:34 -0800294 // The texture parameters are cached in |initialTexParams|.
Brian Salomon0f396992020-06-19 19:51:21 -0400295 GrGLuint createTexture(SkISize dimensions,
296 GrGLFormat,
297 GrGLenum target,
298 GrRenderable,
299 GrGLTextureParameters::SamplerOverriddenState*,
Leon Scroggins III63dee7e2021-11-17 13:18:37 -0500300 int mipLevelCount,
301 GrProtected isProtected);
erikchen9a1ed5d2016-02-10 16:32:34 -0800302
Robert Phillips2716daf2020-01-23 12:53:42 -0500303 GrGLuint createCompressedTexture2D(SkISize dimensions,
Greg Daniel01f278c2020-06-12 16:58:17 -0400304 SkImage::CompressionType compression,
Robert Phillips3a833922020-01-21 15:25:58 -0500305 GrGLFormat,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400306 GrMipmapped,
Greg Danielaaf738c2020-07-10 09:30:33 -0400307 GrGLTextureParameters::SamplerOverriddenState*);
Brian Salomonbb8dde82019-06-27 10:52:13 -0400308
Brian Salomone2078f12021-05-24 12:40:46 -0400309 bool onReadPixels(GrSurface*,
310 SkIRect,
311 GrColorType surfaceColorType,
312 GrColorType dstColorType,
313 void*,
Brian Salomonf77c1462019-08-01 15:19:29 -0400314 size_t rowBytes) override;
bsalomond95263c2014-12-16 13:05:12 -0800315
Brian Salomone2078f12021-05-24 12:40:46 -0400316 bool onWritePixels(GrSurface*,
317 SkIRect,
318 GrColorType surfaceColorType,
319 GrColorType srcColorType,
320 const GrMipLevel[],
321 int mipLevelCount,
Greg Danielb20d7e52019-09-03 13:54:39 -0400322 bool prepForTexSampling) override;
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000323
Brian Salomone2078f12021-05-24 12:40:46 -0400324 bool onTransferPixelsTo(GrTexture*,
325 SkIRect,
326 GrColorType textureColorType,
327 GrColorType bufferColorType,
328 sk_sp<GrGpuBuffer>,
329 size_t offset,
Greg Daniel5ad5a372021-02-01 13:34:04 -0500330 size_t rowBytes) override;
Brian Salomone2078f12021-05-24 12:40:46 -0400331
332 bool onTransferPixelsFrom(GrSurface*,
333 SkIRect,
334 GrColorType surfaceColorType,
335 GrColorType bufferColorType,
336 sk_sp<GrGpuBuffer>,
337 size_t offset) override;
338
339 bool readOrTransferPixelsFrom(GrSurface*,
340 SkIRect rect,
341 GrColorType surfaceColorType,
342 GrColorType dstColorType,
343 void* offsetOrPtr,
344 int rowWidthInPixels);
jvanverth17aa0472016-01-05 10:41:27 -0800345
Greg Danielf76259e2021-02-04 12:14:04 -0500346 // Unbinds xfer buffers from GL for operations that don't need them.
347 // Before calling any variation of TexImage, TexSubImage, etc..., call this with
348 // GrGpuBufferType::kXferCpuToGpu to ensure that the PIXEL_UNPACK_BUFFER is unbound.
349 // Before calling ReadPixels and reading back into cpu memory call this with
350 // GrGpuBufferType::kXferGpuToCpu to ensure that the PIXEL_PACK_BUFFER is unbound.
351 void unbindXferBuffer(GrGpuBufferType type);
Brian Osman9b560242017-09-05 15:34:52 -0400352
Jim Van Verthbb61fe32020-07-07 16:39:04 -0400353 void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override;
bsalomon@google.com6f379512011-11-16 20:36:03 +0000354
Brian Salomon930f9392018-06-20 16:25:26 -0400355 bool onRegenerateMipMapLevels(GrTexture*) override;
356
Greg Daniel46cfbc62019-06-07 11:43:30 -0400357 bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
Greg Daniele227fe42019-08-21 13:52:24 -0400358 const SkIPoint& dstPoint) override;
joshualitt1cbdcde2015-08-21 11:53:29 -0700359
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000360 // binds texture unit in GL
bsalomon@google.com8531c1c2011-01-13 19:52:45 +0000361 void setTextureUnit(int unitIdx);
reed@google.comac10a2d2010-12-22 21:39:39 +0000362
Chris Daltonbbb3f642019-07-24 12:25:08 -0400363 void flushBlendAndColorWrite(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000364
Greg Danielfe159622020-04-10 17:43:51 +0000365 void addFinishedProc(GrGpuFinishedProc finishedProc,
366 GrGpuFinishedContext finishedContext) override;
367
Greg Daniel65476e02020-10-27 09:20:20 -0400368 GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*,
Chris Daltone0fe23a2021-04-23 13:11:44 -0600369 bool useMultisampleFBO,
Greg Daniel65476e02020-10-27 09:20:20 -0400370 GrAttachment*,
371 GrSurfaceOrigin,
372 const SkIRect&,
373 const GrOpsRenderPass::LoadAndStoreInfo&,
374 const GrOpsRenderPass::StencilLoadAndStoreInfo&,
375 const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
376 GrXferBarrierFlags renderPassXferBarriers) override;
377
Greg Danielfe159622020-04-10 17:43:51 +0000378 bool onSubmitToGpu(bool syncCpu) override;
Greg Daniel51316782017-08-02 15:10:09 +0000379
Brian Salomonb0d8b762019-05-06 16:58:22 -0400380 bool waitSync(GrGLsync, uint64_t timeout, bool flush);
381
Chris Dalton7ad3aa22021-06-08 10:10:33 -0600382 bool copySurfaceAsDraw(GrSurface* dst, bool drawToMultisampleFBO, GrSurface* src,
383 const SkIRect& srcRect, const SkIPoint& dstPoint);
Greg Daniel46cfbc62019-06-07 11:43:30 -0400384 void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
385 const SkIPoint& dstPoint);
386 bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
387 const SkIPoint& dstPoint);
bsalomon6df86402015-06-01 10:41:49 -0700388
Robert Phillipsae67c522021-03-03 11:03:38 -0500389 class ProgramCache : public GrThreadSafePipelineBuilder {
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000390 public:
Robert Phillips962708f2021-03-03 14:42:04 -0500391 ProgramCache(int runtimeProgramCacheSize);
Robert Phillipsae67c522021-03-03 11:03:38 -0500392 ~ProgramCache() override;
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000393
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000394 void abandon();
Brian Osman0b8bb882019-04-12 11:47:19 -0400395 void reset();
Robert Phillips962708f2021-03-03 14:42:04 -0500396 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
Robert Phillips962708f2021-03-03 14:42:04 -0500397 const GrProgramInfo&);
Robert Phillips22970172021-03-22 11:26:45 -0400398 sk_sp<GrGLProgram> findOrCreateProgram(GrDirectContext*,
399 const GrProgramDesc&,
400 const GrProgramInfo&,
401 Stats::ProgramCacheResult*);
Robert Phillips962708f2021-03-03 14:42:04 -0500402 bool precompileShader(GrDirectContext*, const SkData& key, const SkData& data);
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000403
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000404 private:
bsalomon@google.com2db3ded2013-05-22 14:34:04 +0000405 struct Entry;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000406
Greg Daniel374f96c2021-04-21 10:32:34 -0400407 sk_sp<GrGLProgram> findOrCreateProgramImpl(GrDirectContext*,
408 const GrProgramDesc&,
409 const GrProgramInfo&,
410 Stats::ProgramCacheResult*);
Robert Phillips979b2232020-02-20 10:47:29 -0500411
Ethan Nicholas1b9924f2016-12-15 15:28:42 -0500412 struct DescHash {
413 uint32_t operator()(const GrProgramDesc& desc) const {
414 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
415 }
416 };
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000417
Ethan Nicholas1b9924f2016-12-15 15:28:42 -0500418 SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
bsalomon@google.comc1d2a582012-06-01 15:08:19 +0000419 };
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000420
Chris Dalton5a2f9622019-12-27 14:56:38 -0700421 void flushPatchVertexCount(uint8_t count);
422
egdaniel080e6732014-12-22 07:35:52 -0800423 void flushColorWrite(bool writeColor);
Brian Salomon07bc9a22020-12-02 13:37:16 -0500424 void flushClearColor(std::array<float, 4>);
bsalomon@google.comc96cb3a2012-06-04 19:31:00 +0000425
Brian Salomond818ebf2018-07-02 14:08:49 +0000426 // flushes the scissor. see the note on flushBoundTextureAndParams about
427 // flushing the scissor after that function is called.
Robert Phillipsedc5b4d2021-01-06 13:06:23 -0500428 void flushScissor(const GrScissorState& scissorState, int rtHeight, GrSurfaceOrigin rtOrigin) {
Chris Dalton2e7ed262020-02-21 15:17:59 -0700429 this->flushScissorTest(GrScissorTest(scissorState.enabled()));
430 if (scissorState.enabled()) {
Robert Phillipsedc5b4d2021-01-06 13:06:23 -0500431 this->flushScissorRect(scissorState.rect(), rtHeight, rtOrigin);
Chris Dalton2e7ed262020-02-21 15:17:59 -0700432 }
433 }
434 void flushScissorTest(GrScissorTest);
bsalomon@google.coma3201942012-06-21 19:58:20 +0000435
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400436 void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
csmartdalton28341fa2016-08-17 10:00:21 -0700437 void disableWindowRectangles();
438
Brian Salomond978b902019-02-07 15:09:18 -0500439 int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); }
440
441 // Binds a texture to a target on the "scratch" texture unit to use for texture operations
Chris Daltoneb694b72020-03-16 09:25:50 -0600442 // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw). It
443 // ensures that such operations don't negatively interact with draws. The active texture unit
444 // and the binding for 'target' will change.
Brian Salomond978b902019-02-07 15:09:18 -0500445 void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
reed@google.comac10a2d2010-12-22 21:39:39 +0000446
Brian Salomon1fabd512018-02-09 09:54:25 -0500447 // The passed bounds contains the render target's color values that will subsequently be
448 // written.
Chris Dalton27d82782021-04-07 19:04:36 -0600449 void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO, GrSurfaceOrigin,
450 const SkIRect& bounds);
Chris Daltonc8ece3d2018-07-30 15:03:45 -0600451 // This version has an implicit bounds of the entire render target.
Chris Dalton27d82782021-04-07 19:04:36 -0600452 void flushRenderTarget(GrGLRenderTarget*, bool useMultisampleFBO);
Brian Salomon1fabd512018-02-09 09:54:25 -0500453 // This version can be used when the render target's colors will not be written.
Chris Dalton27d82782021-04-07 19:04:36 -0600454 void flushRenderTargetNoColorWrites(GrGLRenderTarget*, bool useMultisampleFBO);
bsalomon083617b2016-02-12 12:10:14 -0800455
Chris Dalton71713f62019-04-18 12:41:03 -0600456 void flushStencil(const GrStencilSettings&, GrSurfaceOrigin);
csmartdaltonc7d85332016-10-26 10:13:46 -0700457 void disableStencil();
bsalomon083617b2016-02-12 12:10:14 -0800458
Chris Daltonce425af2019-12-16 10:39:03 -0700459 void flushConservativeRasterState(bool enable);
460
Chris Dalton1215cda2019-12-17 21:44:04 -0700461 void flushWireframeState(bool enable);
462
brianosman33f6b3f2016-06-02 05:49:21 -0700463 void flushFramebufferSRGB(bool enable);
464
Brian Salomon22558932020-05-15 14:46:34 -0400465 // Uploads src data of a color type to the currently bound texture on the active texture unit.
466 // The caller specifies color type that the texture is being used with, which may be different
467 // than the src color type. This fails if the combination of texture format, texture color type,
468 // and src data color type are not valid. No conversion is performed on the data before passing
469 // it to GL. 'dstRect' must be the texture bounds if mipLevelCount is greater than 1.
470 bool uploadColorTypeTexData(GrGLFormat textureFormat,
471 GrColorType textureColorType,
472 SkISize texDims,
473 GrGLenum target,
474 SkIRect dstRect,
475 GrColorType srcColorType,
476 const GrMipLevel texels[],
477 int mipLevelCount);
478
479 // Uploads a constant color to a texture using the "default" format and color type. Overwrites
480 // entire levels. Bit n in 'levelMask' indicates whether level n should be written. This
481 // function doesn't know if MIP levels have been allocated, thus levelMask should not have bits
482 // beyond the low bit set if the texture is not MIP mapped.
483 bool uploadColorToTex(GrGLFormat textureFormat,
484 SkISize texDims,
485 GrGLenum target,
Brian Salomon71283232021-04-08 12:45:58 -0400486 std::array<float, 4> color,
Brian Salomon22558932020-05-15 14:46:34 -0400487 uint32_t levelMask);
488
489 // Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be
490 // the texture bounds if mipLevelCount is greater than 1.
491 void uploadTexData(SkISize dimensions,
492 GrGLenum target,
493 SkIRect dstRect,
494 GrGLenum externalFormat,
495 GrGLenum externalType,
496 size_t bpp,
497 const GrMipLevel texels[],
498 int mipLevelCount);
bsalomon@google.com0650e812011-04-08 18:07:53 +0000499
Greg Daniel7bfc9132019-08-14 14:23:53 -0400500 // Helper for onCreateCompressedTexture. Compressed textures are read-only so we only use this
501 // to populate a new texture. Returns false if we failed to create and upload the texture.
Greg Daniel01f278c2020-06-12 16:58:17 -0400502 bool uploadCompressedTexData(SkImage::CompressionType compressionType,
503 GrGLFormat,
Robert Phillipsb915c942019-12-17 14:44:37 -0500504 SkISize dimensions,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400505 GrMipmapped,
Greg Daniel7bfc9132019-08-14 14:23:53 -0400506 GrGLenum target,
Robert Phillips9f744f72019-12-19 19:14:33 -0500507 const void* data, size_t dataSize);
Jim Van Verth1676cb92019-01-15 13:24:45 -0500508
Brian Salomond8575452020-02-25 12:13:29 -0500509 // Calls one of various versions of renderBufferStorageMultisample.
510 bool renderbufferStorageMSAA(const GrGLContext& ctx, int sampleCount, GrGLenum format,
511 int width, int height);
512
Brian Salomonea4ad302019-08-07 13:04:55 -0400513 bool createRenderTargetObjects(const GrGLTexture::Desc&,
514 int sampleCount,
515 GrGLRenderTarget::IDs*);
egdanield803f272015-03-18 13:01:52 -0700516 enum TempFBOTarget {
517 kSrc_TempFBOTarget,
518 kDst_TempFBOTarget
519 };
egdaniel0f5f9672015-02-03 11:10:51 -0800520
Brian Salomond17b4a62017-05-23 16:53:47 -0400521 // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
522 // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
523 // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
Brian Salomond2a8ae22019-09-10 16:03:59 -0400524 void bindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget,
Brian Salomon71d9d842016-11-03 13:42:00 -0400525 TempFBOTarget tempFBOTarget);
egdaniel0f5f9672015-02-03 11:10:51 -0800526
Brian Salomon71d9d842016-11-03 13:42:00 -0400527 // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
Brian Salomond2a8ae22019-09-10 16:03:59 -0400528 void unbindSurfaceFBOForPixelOps(GrSurface* surface, int mipLevel, GrGLenum fboTarget);
robertphillips754f4e92014-09-18 13:52:08 -0700529
Kevin Lubickf4def342018-10-04 12:52:50 -0400530#ifdef SK_ENABLE_DUMP_GPU
Brian Osman71a18892017-08-10 10:23:25 -0400531 void onDumpJSON(SkJSONWriter*) const override;
Kevin Lubickf4def342018-10-04 12:52:50 -0400532#endif
Brian Osman71a18892017-08-10 10:23:25 -0400533
Greg Daniel4c6f9b72019-06-06 13:40:59 -0400534 bool createCopyProgram(GrTexture* srcTexture);
brianosman33f6b3f2016-06-02 05:49:21 -0700535 bool createMipmapProgram(int progIdx);
ethannicholas22793252016-01-30 09:59:10 -0800536
Brian Salomon8ab1cc42017-12-07 12:40:00 -0500537 std::unique_ptr<GrGLContext> fGLContext;
538
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000539 // GL program-related state
Robert Phillipsae67c522021-03-03 11:03:38 -0500540 sk_sp<ProgramCache> fProgramCache;
bsalomon@google.com49209392012-06-05 15:13:46 +0000541
542 ///////////////////////////////////////////////////////////////////////////
543 ///@name Caching of GL State
544 ///@{
545 int fHWActiveTextureUnitIdx;
Brian Salomon802cb312018-06-08 18:05:20 -0400546
bsalomon@google.com5739d2c2012-05-31 15:07:19 +0000547 GrGLuint fHWProgramID;
Chris Dalton20e7a532020-02-28 15:37:53 +0000548 sk_sp<GrGLProgram> fHWProgram;
bsalomon@google.com91207482013-02-12 21:45:24 +0000549
bsalomon@google.com49209392012-06-05 15:13:46 +0000550 enum TriState {
551 kNo_TriState,
552 kYes_TriState,
553 kUnknown_TriState
554 };
555
egdanield803f272015-03-18 13:01:52 -0700556 GrGLuint fTempSrcFBOID;
557 GrGLuint fTempDstFBOID;
558
559 GrGLuint fStencilClearFBOID;
bsalomondd3143b2015-02-23 09:27:45 -0800560
bsalomon@google.coma3201942012-06-21 19:58:20 +0000561 // last scissor / viewport scissor state seen by the GL.
562 struct {
Chris Daltond6cda8d2019-09-05 02:30:04 -0600563 TriState fEnabled;
564 GrNativeRect fRect;
bsalomon@google.coma3201942012-06-21 19:58:20 +0000565 void invalidate() {
566 fEnabled = kUnknown_TriState;
567 fRect.invalidate();
568 }
569 } fHWScissorSettings;
570
csmartdalton28341fa2016-08-17 10:00:21 -0700571 class {
572 public:
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700573 bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
574 void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
575 bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
mtklein8b4a2022016-09-26 08:44:47 -0700576 void setDisabled() {
Robert Phillipsfb4a20c2017-08-29 14:46:43 -0400577 fRTOrigin = kTopLeft_GrSurfaceOrigin;
mtklein8b4a2022016-09-26 08:44:47 -0700578 fWindowState.setDisabled();
579 }
csmartdalton28341fa2016-08-17 10:00:21 -0700580
Greg Danielacd66b42019-05-22 16:29:12 -0400581 void set(GrSurfaceOrigin rtOrigin, int width, int height,
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700582 const GrWindowRectsState& windowState) {
583 fRTOrigin = rtOrigin;
Greg Danielacd66b42019-05-22 16:29:12 -0400584 fWidth = width;
585 fHeight = height;
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700586 fWindowState = windowState;
csmartdalton28341fa2016-08-17 10:00:21 -0700587 }
csmartdalton28341fa2016-08-17 10:00:21 -0700588
Greg Danielacd66b42019-05-22 16:29:12 -0400589 bool knownEqualTo(GrSurfaceOrigin rtOrigin, int width, int height,
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700590 const GrWindowRectsState& windowState) const {
csmartdalton28341fa2016-08-17 10:00:21 -0700591 if (!this->valid()) {
592 return false;
593 }
Greg Danielacd66b42019-05-22 16:29:12 -0400594 if (fWindowState.numWindows() &&
595 (fRTOrigin != rtOrigin || fWidth != width || fHeight != height)) {
csmartdalton28341fa2016-08-17 10:00:21 -0700596 return false;
597 }
Brian Salomon9a767722017-03-13 17:57:28 -0400598 return fWindowState == windowState;
csmartdalton28341fa2016-08-17 10:00:21 -0700599 }
600
601 private:
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700602 enum { kInvalidSurfaceOrigin = -1 };
csmartdalton28341fa2016-08-17 10:00:21 -0700603
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700604 int fRTOrigin;
Greg Danielacd66b42019-05-22 16:29:12 -0400605 int fWidth;
606 int fHeight;
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700607 GrWindowRectsState fWindowState;
608 } fHWWindowRectsState;
csmartdalton28341fa2016-08-17 10:00:21 -0700609
Chris Daltond6cda8d2019-09-05 02:30:04 -0600610 GrNativeRect fHWViewport;
bsalomon@google.coma3201942012-06-21 19:58:20 +0000611
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000612 /**
cdaltone2e71c22016-04-07 18:13:29 -0700613 * Tracks vertex attrib array state.
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000614 */
cdaltone2e71c22016-04-07 18:13:29 -0700615 class HWVertexArrayState {
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000616 public:
cdaltone2e71c22016-04-07 18:13:29 -0700617 HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000618
cdaltone2e71c22016-04-07 18:13:29 -0700619 ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000620
bsalomon@google.com6918d482013-03-07 19:09:11 +0000621 void invalidate() {
622 fBoundVertexArrayIDIsValid = false;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000623 fDefaultVertexArrayAttribState.invalidate();
cdaltone2e71c22016-04-07 18:13:29 -0700624 if (fCoreProfileVertexArray) {
625 fCoreProfileVertexArray->invalidateCachedState();
commit-bot@chromium.orgce6da4d2013-09-09 14:55:37 +0000626 }
bsalomon@google.com6918d482013-03-07 19:09:11 +0000627 }
628
629 void notifyVertexArrayDelete(GrGLuint id) {
630 if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
631 // Does implicit bind to 0
632 fBoundVertexArrayID = 0;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000633 }
634 }
635
bsalomon861e1032014-12-16 07:33:49 -0800636 void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000637 if (!gpu->glCaps().vertexArrayObjectSupport()) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000638 SkASSERT(0 == arrayID);
bsalomon@google.com6918d482013-03-07 19:09:11 +0000639 return;
640 }
641 if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
642 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
643 fBoundVertexArrayIDIsValid = true;
644 fBoundVertexArrayID = arrayID;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000645 }
646 }
647
bsalomon@google.com6918d482013-03-07 19:09:11 +0000648 /**
cdaltone2e71c22016-04-07 18:13:29 -0700649 * Binds the vertex array that should be used for internal draws, and returns its attrib
650 * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
Kevin Lubickbe03ef12021-06-16 15:28:00 -0400651 * case we use a placeholder array instead.
cdaltone2e71c22016-04-07 18:13:29 -0700652 *
Chris Daltond42d2002020-02-28 12:05:04 -0700653 * If an index buffer is provided, it will be bound to the vertex array. Otherwise the
cdaltone2e71c22016-04-07 18:13:29 -0700654 * index buffer binding will be left unchanged.
655 *
656 * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
bsalomon@google.com6918d482013-03-07 19:09:11 +0000657 */
csmartdalton485a1202016-07-13 10:16:32 -0700658 GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
bsalomon6df86402015-06-01 10:41:49 -0700659
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000660 private:
Robert Phillips294870f2016-11-11 12:38:40 -0500661 GrGLuint fBoundVertexArrayID;
662 bool fBoundVertexArrayIDIsValid;
mtklein044d3c12016-04-06 18:24:34 -0700663
bsalomon@google.com6918d482013-03-07 19:09:11 +0000664 // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
jvanverth39edf762014-12-22 11:44:19 -0800665 // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
666 // GrGLGpu.
Robert Phillips294870f2016-11-11 12:38:40 -0500667 GrGLAttribArrayState fDefaultVertexArrayAttribState;
bsalomon@google.com880b8fc2013-02-19 20:17:28 +0000668
cdaltone2e71c22016-04-07 18:13:29 -0700669 // This is used when we're using a core profile.
Robert Phillips294870f2016-11-11 12:38:40 -0500670 GrGLVertexArray* fCoreProfileVertexArray;
Chris Dalton5a2f9622019-12-27 14:56:38 -0700671 } fHWVertexArrayState;
672
673 uint8_t fHWPatchVertexCount;
bsalomon@google.com5782d712011-01-21 21:03:59 +0000674
cdaltone2e71c22016-04-07 18:13:29 -0700675 struct {
Robert Phillips294870f2016-11-11 12:38:40 -0500676 GrGLenum fGLTarget;
677 GrGpuResource::UniqueID fBoundBufferUniqueID;
678 bool fBufferZeroKnownBound;
cdaltone2e71c22016-04-07 18:13:29 -0700679
680 void invalidate() {
Robert Phillips294870f2016-11-11 12:38:40 -0500681 fBoundBufferUniqueID.makeInvalid();
cdaltone2e71c22016-04-07 18:13:29 -0700682 fBufferZeroKnownBound = false;
683 }
Brian Salomonae64c192019-02-05 09:41:37 -0500684 } fHWBufferState[kGrGpuBufferTypeCount];
685
686 auto* hwBufferState(GrGpuBufferType type) {
687 unsigned typeAsUInt = static_cast<unsigned>(type);
688 SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState));
Greg Daniel87d784f2021-02-02 15:36:06 -0500689 SkASSERT(type != GrGpuBufferType::kUniform);
Brian Salomonae64c192019-02-05 09:41:37 -0500690 return &fHWBufferState[typeAsUInt];
691 }
cdaltonc1613102016-03-16 07:48:20 -0700692
Greg Daniel78be37f2020-04-14 16:40:35 -0400693 enum class FlushType {
694 kIfRequired,
695 kForce,
696 };
697
698 // This calls glFlush if it is required for previous operations or kForce is passed.
699 void flush(FlushType flushType = FlushType::kIfRequired);
700
701 void setNeedsFlush() { fNeedsGLFlush = true; }
702
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000703 struct {
cdalton8917d622015-05-06 13:40:21 -0700704 GrBlendEquation fEquation;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000705 GrBlendCoeff fSrcCoeff;
706 GrBlendCoeff fDstCoeff;
Brian Osman422f95b2018-11-05 16:49:04 -0500707 SkPMColor4f fConstColor;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000708 bool fConstColorValid;
709 TriState fEnabled;
710
711 void invalidate() {
Mike Klein36743362018-11-06 08:23:30 -0500712 fEquation = kIllegal_GrBlendEquation;
713 fSrcCoeff = kIllegal_GrBlendCoeff;
714 fDstCoeff = kIllegal_GrBlendCoeff;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000715 fConstColorValid = false;
716 fEnabled = kUnknown_TriState;
717 }
Robert Phillips294870f2016-11-11 12:38:40 -0500718 } fHWBlendState;
bsalomon@google.coma4d8fc22012-05-21 13:21:46 +0000719
Chris Daltonce425af2019-12-16 10:39:03 -0700720 TriState fHWConservativeRasterEnabled;
bsalomon54c6fe82015-12-16 11:51:22 -0800721
Chris Dalton1215cda2019-12-17 21:44:04 -0700722 TriState fHWWireframeEnabled;
723
Robert Phillips294870f2016-11-11 12:38:40 -0500724 GrStencilSettings fHWStencilSettings;
Chris Dalton71713f62019-04-18 12:41:03 -0600725 GrSurfaceOrigin fHWStencilOrigin;
Robert Phillips294870f2016-11-11 12:38:40 -0500726 TriState fHWStencilTestEnabled;
bsalomon54c6fe82015-12-16 11:51:22 -0800727
Robert Phillips294870f2016-11-11 12:38:40 -0500728 TriState fHWWriteToColor;
729 GrGpuResource::UniqueID fHWBoundRenderTargetUniqueID;
Chris Dalton27d82782021-04-07 19:04:36 -0600730 bool fHWBoundFramebufferIsMSAA;
Robert Phillips294870f2016-11-11 12:38:40 -0500731 TriState fHWSRGBFramebuffer;
Brian Salomond978b902019-02-07 15:09:18 -0500732
733 class TextureUnitBindings {
734 public:
735 TextureUnitBindings() = default;
736 TextureUnitBindings(const TextureUnitBindings&) = delete;
737 TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
738
739 GrGpuResource::UniqueID boundID(GrGLenum target) const;
Brian Salomon1f05d452019-02-08 12:33:08 -0500740 bool hasBeenModified(GrGLenum target) const;
Brian Salomond978b902019-02-07 15:09:18 -0500741 void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
Brian Salomon1f05d452019-02-08 12:33:08 -0500742 void invalidateForScratchUse(GrGLenum target);
743 void invalidateAllTargets(bool markUnmodified);
Brian Salomond978b902019-02-07 15:09:18 -0500744
745 private:
Brian Salomon1f05d452019-02-08 12:33:08 -0500746 struct TargetBinding {
747 GrGpuResource::UniqueID fBoundResourceID;
748 bool fHasBeenModified = false;
749 };
750 TargetBinding fTargetBindings[3];
Brian Salomond978b902019-02-07 15:09:18 -0500751 };
752 SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
cdaltonaf8bc7d2016-02-05 09:35:20 -0800753
Brian Salomon805cc7a2019-01-28 09:52:34 -0500754 GrGLfloat fHWClearColor[4];
755
Adrienne Walker4ee88512018-05-17 11:37:14 -0700756 GrGLuint fBoundDrawFramebuffer = 0;
757
Brian Salomon57111332018-02-05 15:55:54 -0500758 /** IDs for copy surface program. (3 sampler types) */
bsalomon6df86402015-06-01 10:41:49 -0700759 struct {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400760 GrGLuint fProgram = 0;
761 GrGLint fTextureUniform = 0;
762 GrGLint fTexCoordXformUniform = 0;
763 GrGLint fPosXformUniform = 0;
Brian Salomon57111332018-02-05 15:55:54 -0500764 } fCopyPrograms[3];
Robert Phillips294870f2016-11-11 12:38:40 -0500765 sk_sp<GrGLBuffer> fCopyProgramArrayBuffer;
bsalomon7ea33f52015-11-22 14:51:00 -0800766
brianosman33f6b3f2016-06-02 05:49:21 -0700767 /** IDs for texture mipmap program. (4 filter configurations) */
768 struct {
Brian Salomon43f8bf02017-10-18 08:33:29 -0400769 GrGLuint fProgram = 0;
770 GrGLint fTextureUniform = 0;
771 GrGLint fTexCoordXformUniform = 0;
Robert Phillips294870f2016-11-11 12:38:40 -0500772 } fMipmapPrograms[4];
773 sk_sp<GrGLBuffer> fMipmapProgramArrayBuffer;
brianosman33f6b3f2016-06-02 05:49:21 -0700774
Robert Phillips646e4292017-06-13 12:44:56 -0400775 static int TextureToCopyProgramIdx(GrTexture* texture);
bsalomon6df86402015-06-01 10:41:49 -0700776
brianosman33f6b3f2016-06-02 05:49:21 -0700777 static int TextureSizeToMipmapProgramIdx(int width, int height) {
778 const bool wide = (width > 1) && SkToBool(width & 0x1);
779 const bool tall = (height > 1) && SkToBool(height & 0x1);
780 return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
781 }
782
Chris Daltonda40cd22018-04-16 13:19:58 -0600783 GrPrimitiveType fLastPrimitiveType;
ethannicholas28ef4452016-03-25 09:26:03 -0700784
Brian Salomone2826ab2019-06-04 15:58:31 -0400785 GrGLTextureParameters::ResetTimestamp fResetTimestampForTextureParameters = 0;
786
Brian Salomondc829942018-10-23 16:07:24 -0400787 class SamplerObjectCache;
788 std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
789
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400790 std::unique_ptr<GrGLOpsRenderPass> fCachedOpsRenderPass;
Stephen Whiteb353c9b2020-04-16 14:14:13 -0400791 GrFinishCallbacks fFinishCallbacks;
Chris Dalton674f77a2019-09-30 20:49:39 -0600792
Greg Daniel78be37f2020-04-14 16:40:35 -0400793 // If we've called a command that requires us to call glFlush than this will be set to true
794 // since we defer calling flush until submit time. When we call submitToGpu if this is true then
795 // we call glFlush and reset this to false.
796 bool fNeedsGLFlush = false;
797
Chris Dalton674f77a2019-09-30 20:49:39 -0600798 SkDEBUGCODE(bool fIsExecutingCommandBuffer_DebugOnly = false);
799
kkinnunenccdaa042014-08-20 01:36:23 -0700800 friend class GrGLPathRendering; // For accessing setTextureUnit.
Robert Phillips5b5d84c2018-08-09 15:12:18 -0400801
John Stiles7571f9e2020-09-02 22:42:33 -0400802 using INHERITED = GrGpu;
reed@google.comac10a2d2010-12-22 21:39:39 +0000803};
804
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000805#endif