• 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 "GrGLContext.h"
12 #include "GrGLIRect.h"
13 #include "GrGLPathRendering.h"
14 #include "GrGLProgram.h"
15 #include "GrGLRenderTarget.h"
16 #include "GrGLStencilAttachment.h"
17 #include "GrGLTexture.h"
18 #include "GrGLVertexArray.h"
19 #include "GrGpu.h"
20 #include "GrMesh.h"
21 #include "GrWindowRectsState.h"
22 #include "GrXferProcessor.h"
23 #include "SkLRUCache.h"
24 #include "SkTArray.h"
25 #include "SkTypes.h"
26 
27 class GrGLBuffer;
28 class GrGLGpuRTCommandBuffer;
29 class GrGLGpuTextureCommandBuffer;
30 class GrPipeline;
31 class GrSwizzle;
32 
33 #ifdef SK_DEBUG
34 #define PROGRAM_CACHE_STATS
35 #endif
36 
37 class GrGLGpu final : public GrGpu, private GrMesh::SendToGpuImpl {
38 public:
39     static sk_sp<GrGpu> Make(sk_sp<const GrGLInterface>, const GrContextOptions&, GrContext*);
40     ~GrGLGpu() override;
41 
42     void disconnect(DisconnectType) override;
43 
glContext()44     const GrGLContext& glContext() const { return *fGLContext; }
45 
glInterface()46     const GrGLInterface* glInterface() const { return fGLContext->interface(); }
ctxInfo()47     const GrGLContextInfo& ctxInfo() const { return *fGLContext; }
glStandard()48     GrGLStandard glStandard() const { return fGLContext->standard(); }
glVersion()49     GrGLVersion glVersion() const { return fGLContext->version(); }
glslGeneration()50     GrGLSLGeneration glslGeneration() const { return fGLContext->glslGeneration(); }
glCaps()51     const GrGLCaps& glCaps() const { return *fGLContext->caps(); }
52 
glPathRendering()53     GrGLPathRendering* glPathRendering() {
54         SkASSERT(glCaps().shaderCaps()->pathRenderingSupport());
55         return static_cast<GrGLPathRendering*>(pathRendering());
56     }
57 
58     // Used by GrGLProgram to configure OpenGL state.
59     void bindTexture(int unitIdx, GrSamplerState samplerState, GrGLTexture* texture);
60 
61     // These functions should be used to bind GL objects. They track the GL state and skip redundant
62     // bindings. Making the equivalent glBind calls directly will confuse the state tracking.
bindVertexArray(GrGLuint id)63     void bindVertexArray(GrGLuint id) {
64         fHWVertexArrayState.setVertexArrayID(this, id);
65     }
66 
67     // These callbacks update state tracking when GL objects are deleted. They are called from
68     // GrGLResource onRelease functions.
notifyVertexArrayDelete(GrGLuint id)69     void notifyVertexArrayDelete(GrGLuint id) {
70         fHWVertexArrayState.notifyVertexArrayDelete(id);
71     }
72 
73     // Binds a buffer to the GL target corresponding to 'type', updates internal state tracking, and
74     // returns the GL target the buffer was bound to.
75     // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO.
76     // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly.
77     GrGLenum bindBuffer(GrBufferType type, const GrBuffer*);
78 
79     // The GrGLGpuRTCommandBuffer 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 GrGLRTGpuCommandBuffer.
82     void draw(GrRenderTarget*, GrSurfaceOrigin,
83               const GrPrimitiveProcessor&,
84               const GrPipeline&,
85               const GrPipeline::FixedDynamicState*,
86               const GrPipeline::DynamicStateArrays*,
87               const GrMesh[],
88               int meshCount);
89 
90     // GrMesh::SendToGpuImpl methods. These issue the actual GL draw calls.
91     // Marked final as a hint to the compiler to not use virtual dispatch.
92     void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
93                        int baseVertex) final;
94 
95     void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
96                               int baseIndex, uint16_t minIndexValue, uint16_t maxIndexValue,
97                               const GrBuffer* vertexBuffer, int baseVertex,
98                               GrPrimitiveRestart) final;
99 
100     void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
101                                 int baseVertex, const GrBuffer* instanceBuffer, int instanceCount,
102                                 int baseInstance) final;
103 
104     void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer, int indexCount,
105                                        int baseIndex, const GrBuffer* vertexBuffer, int baseVertex,
106                                        const GrBuffer* instanceBuffer, int instanceCount,
107                                        int baseInstance, GrPrimitiveRestart) final;
108 
109     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
110     // Thus this is the implementation of the clear call for the corresponding passthrough function
111     // on GrGLGpuRTCommandBuffer.
112     void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
113 
114     // The GrGLGpuRTCommandBuffer does not buffer up draws before submitting them to the gpu.
115     // Thus this is the implementation of the clearStencil call for the corresponding passthrough
116     // function on GrGLGpuRTCommandBuffer.
117     void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
118                           GrRenderTarget*, GrSurfaceOrigin);
119 
120     // FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the
121     // stencil buffer as not dirty?
122     void clearStencil(GrRenderTarget*, int clearValue);
123 
124     GrGpuRTCommandBuffer* getCommandBuffer(
125             GrRenderTarget*, GrSurfaceOrigin, const SkRect&,
126             const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
127             const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
128 
129     GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
130 
invalidateBoundRenderTarget()131     void invalidateBoundRenderTarget() {
132         fHWBoundRenderTargetUniqueID.makeInvalid();
133     }
134 
135     GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
136                                                                 int width,
137                                                                 int height) override;
138 #if GR_TEST_UTILS
139     GrBackendTexture createTestingOnlyBackendTexture(const void* pixels, int w, int h,
140                                                      GrColorType colorType, bool isRenderTarget,
141                                                      GrMipMapped mipMapped,
142                                                      size_t rowBytes = 0) override;
143     bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
144     void deleteTestingOnlyBackendTexture(const GrBackendTexture&) override;
145 
146     GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override;
147 
148     void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
149 
glContextForTesting()150     const GrGLContext* glContextForTesting() const override { return &this->glContext(); }
151 
resetShaderCacheForTesting()152     void resetShaderCacheForTesting() const override { fProgramCache->abandon(); }
153 
154     void testingOnly_flushGpuAndSync() override;
155 #endif
156 
157     void submit(GrGpuCommandBuffer* buffer) override;
158 
159     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
160     bool waitFence(GrFence, uint64_t timeout) override;
161     void deleteFence(GrFence) const override;
162 
163     sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
164     sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
165                                             GrResourceProvider::SemaphoreWrapType wrapType,
166                                             GrWrapOwnership ownership) override;
167     void insertSemaphore(sk_sp<GrSemaphore> semaphore) override;
168     void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
169 
170     sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
171 
172     void deleteSync(GrGLsync) const;
173 
174     void insertEventMarker(const char*);
175 
176     void bindFramebuffer(GrGLenum fboTarget, GrGLuint fboid);
177     void deleteFramebuffer(GrGLuint fboid);
178 
179 private:
180     GrGLGpu(std::unique_ptr<GrGLContext>, GrContext*);
181 
182     // GrGpu overrides
183     void onResetContext(uint32_t resetBits) override;
184 
185     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
186 
187     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
188                                      const GrMipLevel texels[], int mipLevelCount) override;
189 
190     sk_sp<GrBuffer> onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
191                                    const void* data) override;
192 
193     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable,
194                                           GrIOType) override;
195     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
196                                                     GrWrapOwnership, GrWrapCacheable) override;
197     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
198     sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
199                                                              int sampleCnt) override;
200 
201     // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
202     // compatible stencil format, or negative if there is no compatible stencil format.
203     int getCompatibleStencilIndex(GrPixelConfig config);
204 
205     void onFBOChanged();
206 
207     // Returns whether the texture is successfully created. On success, the
208     // result is stored in |info|.
209     // The texture is populated with |texels|, if it exists.
210     // The texture parameters are cached in |initialTexParams|.
211     bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget,
212                            GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[],
213                            int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
214 
215     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
216     // render target.
217     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
218 
219     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
220     // render target that has renderTargetConfig. This may have to create a temporary
221     // render target and thus is less preferable than the variant that takes a render target.
222     bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
223 
224     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
225     // render target that has the same config as surfaceForConfig. Calls one of the the two
226     // variations above, depending on whether the surface is a render target or not.
227     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
228 
229     bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType,
230                       void* buffer, size_t rowBytes) override;
231 
232     bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType,
233                        const GrMipLevel texels[], int mipLevelCount) override;
234 
235     bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrColorType,
236                           GrBuffer* transferBuffer, size_t offset, size_t rowBytes) override;
237 
238     // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
239     // PIXEL_UNPACK_BUFFER is unbound.
240     void unbindCpuToGpuXferBuffer();
241 
242     void onResolveRenderTarget(GrRenderTarget* target) override;
243 
244     bool onRegenerateMipMapLevels(GrTexture*) override;
245 
246     bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
247                        GrSurface* src, GrSurfaceOrigin srcOrigin,
248                        const SkIRect& srcRect, const SkIPoint& dstPoint,
249                        bool canDiscardOutsideDstRect) override;
250 
251     // binds texture unit in GL
252     void setTextureUnit(int unitIdx);
253 
254     /**
255      * primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() *
256      * numPrimitiveProcessorTextureSets entries.
257      */
258     void resolveAndGenerateMipMapsForProcessorTextures(
259             const GrPrimitiveProcessor&, const GrPipeline&,
260             const GrTextureProxy* const primitiveProcessorTextures[],
261             int numPrimitiveProcessorTextureSets);
262 
263     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
264     // willDrawPoints must be true if point primitives will be rendered after setting the GL state.
265     // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
266     // state entries in each array.
267     bool flushGLState(GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&,
268                       const GrPipeline&, const GrPipeline::FixedDynamicState*,
269                       const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength,
270                       bool willDrawPoints);
271 
272     void flushProgram(sk_sp<GrGLProgram>);
273 
274     // Version for programs that aren't GrGLProgram.
275     void flushProgram(GrGLuint);
276 
277     // Sets up vertex/instance attribute pointers and strides.
278     void setupGeometry(const GrBuffer* indexBuffer,
279                        const GrBuffer* vertexBuffer,
280                        int baseVertex,
281                        const GrBuffer* instanceBuffer,
282                        int baseInstance,
283                        GrPrimitiveRestart);
284 
285     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
286 
287     void onFinishFlush(bool insertedSemaphores) override;
288 
289     bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
290                            GrSurface* src, GrSurfaceOrigin srcOrigin,
291                            const SkIRect& srcRect, const SkIPoint& dstPoint);
292     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
293                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
294                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
295     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
296                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
297                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
298 
299     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
300 
301     class ProgramCache : public ::SkNoncopyable {
302     public:
303         ProgramCache(GrGLGpu* gpu);
304         ~ProgramCache();
305 
306         void abandon();
307         GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin,
308                                 const GrPrimitiveProcessor&,
309                                 const GrTextureProxy* const primProcProxies[],
310                                 const GrPipeline&, bool hasPointSize);
311 
312     private:
313         // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
314         // shader before evicting from the cache.
315         static const int kMaxEntries = 128;
316 
317         struct Entry;
318 
319         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
320         // of the index of where it should be inserted.
321         int search(const GrProgramDesc& desc) const;
322 
323         struct DescHash {
operatorDescHash324             uint32_t operator()(const GrProgramDesc& desc) const {
325                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
326             }
327         };
328 
329         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
330 
331         GrGLGpu*                    fGpu;
332 #ifdef PROGRAM_CACHE_STATS
333         int                         fTotalRequests;
334         int                         fCacheMisses;
335         int                         fHashMisses; // cache hit but hash table missed
336 #endif
337     };
338 
339     void flushColorWrite(bool writeColor);
340     void flushClearColor(GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a);
341 
342     // flushes the scissor. see the note on flushBoundTextureAndParams about
343     // flushing the scissor after that function is called.
344     void flushScissor(const GrScissorState&,
345                       const GrGLIRect& rtViewport,
346                       GrSurfaceOrigin rtOrigin);
347 
348     // disables the scissor
349     void disableScissor();
350 
351     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
352     void disableWindowRectangles();
353 
354     // sets a texture unit to use for texture operations other than binding a texture to a program.
355     // ensures that such operations don't negatively interact with tracking bound textures.
356     void setScratchTextureUnit();
357 
358     // The passed bounds contains the render target's color values that will subsequently be
359     // written.
360     void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
361     // This version has an implicit bounds of the entire render target.
362     void flushRenderTarget(GrGLRenderTarget*);
363     // This version can be used when the render target's colors will not be written.
364     void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
365 
366     // Need not be called if flushRenderTarget is used.
367     void flushViewport(const GrGLIRect&);
368 
369     void flushStencil(const GrStencilSettings&);
370     void disableStencil();
371 
372     // rt is used only if useHWAA is true.
373     void flushHWAAState(GrRenderTarget* rt, bool useHWAA, bool stencilEnabled);
374 
375     void flushFramebufferSRGB(bool enable);
376 
377     // helper for onCreateTexture and writeTexturePixels
378     enum UploadType {
379         kNewTexture_UploadType,   // we are creating a new texture
380         kWrite_UploadType,        // we are using TexSubImage2D to copy data to an existing texture
381     };
382     bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, GrGLenum target,
383                        UploadType uploadType, int left, int top, int width, int height,
384                        GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount,
385                        GrMipMapsStatus* mipMapsStatus = nullptr);
386 
387     // helper for onCreateCompressedTexture. Compressed textures are read-only so we
388     // only use this to populate a new texture.
389     bool uploadCompressedTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
390                                  GrGLenum target, GrPixelConfig dataConfig,
391                                  const GrMipLevel texels[], int mipLevelCount,
392                                  GrMipMapsStatus* mipMapsStatus = nullptr);
393 
394     bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
395                                    GrGLRenderTarget::IDDesc*);
396 
397     enum TempFBOTarget {
398         kSrc_TempFBOTarget,
399         kDst_TempFBOTarget
400     };
401 
402     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
403     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
404     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
405     void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
406                                    TempFBOTarget tempFBOTarget);
407 
408     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
409     void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface);
410 
411 #ifdef SK_ENABLE_DUMP_GPU
412     void onDumpJSON(SkJSONWriter*) const override;
413 #endif
414 
415     bool createCopyProgram(GrTexture* srcTexture);
416     bool createMipmapProgram(int progIdx);
417 
418     std::unique_ptr<GrGLContext> fGLContext;
419 
420     // GL program-related state
421     ProgramCache*               fProgramCache;
422 
423     ///////////////////////////////////////////////////////////////////////////
424     ///@name Caching of GL State
425     ///@{
426     int                         fHWActiveTextureUnitIdx;
427 
428     GrGLuint                    fHWProgramID;
429     sk_sp<GrGLProgram>          fHWProgram;
430 
431     enum TriState {
432         kNo_TriState,
433         kYes_TriState,
434         kUnknown_TriState
435     };
436 
437     GrGLuint                    fTempSrcFBOID;
438     GrGLuint                    fTempDstFBOID;
439 
440     GrGLuint                    fStencilClearFBOID;
441 
442     // last scissor / viewport scissor state seen by the GL.
443     struct {
444         TriState    fEnabled;
445         GrGLIRect   fRect;
invalidate__anon4d766a4c0108446         void invalidate() {
447             fEnabled = kUnknown_TriState;
448             fRect.invalidate();
449         }
450     } fHWScissorSettings;
451 
452     class {
453     public:
valid()454         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()455         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()456         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()457         void setDisabled() {
458             fRTOrigin = kTopLeft_GrSurfaceOrigin;
459             fWindowState.setDisabled();
460         }
461 
set(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)462         void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
463                  const GrWindowRectsState& windowState) {
464             fRTOrigin = rtOrigin;
465             fViewport = viewport;
466             fWindowState = windowState;
467         }
468 
knownEqualTo(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)469         bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
470                           const GrWindowRectsState& windowState) const {
471             if (!this->valid()) {
472                 return false;
473             }
474             if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
475                 return false;
476             }
477             return fWindowState == windowState;
478         }
479 
480     private:
481         enum { kInvalidSurfaceOrigin = -1 };
482 
483         int                  fRTOrigin;
484         GrGLIRect            fViewport;
485         GrWindowRectsState   fWindowState;
486     } fHWWindowRectsState;
487 
488     GrGLIRect                   fHWViewport;
489 
490     /**
491      * Tracks vertex attrib array state.
492      */
493     class HWVertexArrayState {
494     public:
HWVertexArrayState()495         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
496 
~HWVertexArrayState()497         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
498 
invalidate()499         void invalidate() {
500             fBoundVertexArrayIDIsValid = false;
501             fDefaultVertexArrayAttribState.invalidate();
502             if (fCoreProfileVertexArray) {
503                 fCoreProfileVertexArray->invalidateCachedState();
504             }
505         }
506 
notifyVertexArrayDelete(GrGLuint id)507         void notifyVertexArrayDelete(GrGLuint id) {
508             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
509                 // Does implicit bind to 0
510                 fBoundVertexArrayID = 0;
511             }
512         }
513 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)514         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
515             if (!gpu->glCaps().vertexArrayObjectSupport()) {
516                 SkASSERT(0 == arrayID);
517                 return;
518             }
519             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
520                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
521                 fBoundVertexArrayIDIsValid = true;
522                 fBoundVertexArrayID = arrayID;
523             }
524         }
525 
526         /**
527          * Binds the vertex array that should be used for internal draws, and returns its attrib
528          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
529          * case we use a dummy array instead.
530          *
531          * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
532          * index buffer binding will be left unchanged.
533          *
534          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
535          */
536         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
537 
538     private:
539         GrGLuint             fBoundVertexArrayID;
540         bool                 fBoundVertexArrayIDIsValid;
541 
542         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
543         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
544         // GrGLGpu.
545         GrGLAttribArrayState fDefaultVertexArrayAttribState;
546 
547         // This is used when we're using a core profile.
548         GrGLVertexArray*     fCoreProfileVertexArray;
549     }                                       fHWVertexArrayState;
550 
551     struct {
552         GrGLenum                fGLTarget;
553         GrGpuResource::UniqueID fBoundBufferUniqueID;
554         bool                    fBufferZeroKnownBound;
555 
invalidate__anon4d766a4c0308556         void invalidate() {
557             fBoundBufferUniqueID.makeInvalid();
558             fBufferZeroKnownBound = false;
559         }
560     }                                       fHWBufferState[kGrBufferTypeCount];
561 
562     struct {
563         GrBlendEquation fEquation;
564         GrBlendCoeff    fSrcCoeff;
565         GrBlendCoeff    fDstCoeff;
566         SkPMColor4f     fConstColor;
567         bool            fConstColorValid;
568         TriState        fEnabled;
569 
invalidate__anon4d766a4c0408570         void invalidate() {
571             fEquation = kIllegal_GrBlendEquation;
572             fSrcCoeff = kIllegal_GrBlendCoeff;
573             fDstCoeff = kIllegal_GrBlendCoeff;
574             fConstColorValid = false;
575             fEnabled = kUnknown_TriState;
576         }
577     }                                       fHWBlendState;
578 
579     TriState                                fMSAAEnabled;
580 
581     GrStencilSettings                       fHWStencilSettings;
582     TriState                                fHWStencilTestEnabled;
583 
584 
585     TriState                                fHWWriteToColor;
586     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
587     TriState                                fHWSRGBFramebuffer;
588     SkTArray<GrGpuResource::UniqueID, true> fHWBoundTextureUniqueIDs;
589 
590     GrGLfloat fHWClearColor[4];
591 
592     GrGLuint fBoundDrawFramebuffer = 0;
593 
594     // EXT_raster_multisample.
595     TriState                                fHWRasterMultisampleEnabled;
596     int                                     fHWNumRasterSamples;
597     ///@}
598 
599     /** IDs for copy surface program. (3 sampler types) */
600     struct {
601         GrGLuint    fProgram = 0;
602         GrGLint     fTextureUniform = 0;
603         GrGLint     fTexCoordXformUniform = 0;
604         GrGLint     fPosXformUniform = 0;
605     }                                       fCopyPrograms[3];
606     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
607 
608     /** IDs for texture mipmap program. (4 filter configurations) */
609     struct {
610         GrGLuint    fProgram = 0;
611         GrGLint     fTextureUniform = 0;
612         GrGLint     fTexCoordXformUniform = 0;
613     }                                       fMipmapPrograms[4];
614     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
615 
616     static int TextureToCopyProgramIdx(GrTexture* texture);
617 
TextureSizeToMipmapProgramIdx(int width,int height)618     static int TextureSizeToMipmapProgramIdx(int width, int height) {
619         const bool wide = (width > 1) && SkToBool(width & 0x1);
620         const bool tall = (height > 1) && SkToBool(height & 0x1);
621         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
622     }
623 
624     GrPrimitiveType fLastPrimitiveType;
625 
626     class SamplerObjectCache;
627     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
628 
629     std::unique_ptr<GrGLGpuRTCommandBuffer>      fCachedRTCommandBuffer;
630     std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer;
631 
632     friend class GrGLPathRendering; // For accessing setTextureUnit.
633 
634     typedef GrGpu INHERITED;
635 };
636 
637 #endif
638