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