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