• 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(GrGpuBufferType 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 onResetTextureBindings() override;
186 
187     void querySampleLocations(
188             GrRenderTarget*, const GrStencilSettings&, SkTArray<SkPoint>*) override;
189 
190     void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
191 
192     sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
193                                      const GrMipLevel texels[], int mipLevelCount) override;
194 
195     sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType intendedType, GrAccessPattern,
196                                       const void* data) override;
197 
198     sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership, GrWrapCacheable,
199                                           GrIOType) override;
200     sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, int sampleCnt,
201                                                     GrWrapOwnership, GrWrapCacheable) override;
202     sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
203     sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
204                                                              int sampleCnt) override;
205 
206     // Given a GrPixelConfig return the index into the stencil format array on GrGLCaps to a
207     // compatible stencil format, or negative if there is no compatible stencil format.
208     int getCompatibleStencilIndex(GrPixelConfig config);
209 
210     void onFBOChanged();
211 
212     // Returns whether the texture is successfully created. On success, the
213     // result is stored in |info|.
214     // The texture is populated with |texels|, if it exists.
215     // The texture parameters are cached in |initialTexParams|.
216     bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info, bool renderTarget,
217                            GrGLTexture::SamplerParams* initialTexParams, const GrMipLevel texels[],
218                            int mipLevelCount, GrMipMapsStatus* mipMapsStatus);
219 
220     // Checks whether glReadPixels can be called to get pixel values in readConfig from the
221     // render target.
222     bool readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig);
223 
224     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
225     // render target that has renderTargetConfig. This may have to create a temporary
226     // render target and thus is less preferable than the variant that takes a render target.
227     bool readPixelsSupported(GrPixelConfig renderTargetConfig, GrPixelConfig readConfig);
228 
229     // Checks whether glReadPixels can be called to get pixel values in readConfig from a
230     // render target that has the same config as surfaceForConfig. Calls one of the the two
231     // variations above, depending on whether the surface is a render target or not.
232     bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
233 
234     bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType,
235                       void* buffer, size_t rowBytes) override;
236 
237     bool onWritePixels(GrSurface*, int left, int top, int width, int height, GrColorType,
238                        const GrMipLevel texels[], int mipLevelCount) override;
239 
240     bool onTransferPixels(GrTexture*, int left, int top, int width, int height, GrColorType,
241                           GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override;
242 
243     // Before calling any variation of TexImage, TexSubImage, etc..., call this to ensure that the
244     // PIXEL_UNPACK_BUFFER is unbound.
245     void unbindCpuToGpuXferBuffer();
246 
247     void onResolveRenderTarget(GrRenderTarget* target) override;
248 
249     bool onRegenerateMipMapLevels(GrTexture*) override;
250 
251     bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
252                        GrSurface* src, GrSurfaceOrigin srcOrigin,
253                        const SkIRect& srcRect, const SkIPoint& dstPoint,
254                        bool canDiscardOutsideDstRect) override;
255 
256     // binds texture unit in GL
257     void setTextureUnit(int unitIdx);
258 
259     /**
260      * primitiveProcessorTextures must contain GrPrimitiveProcessor::numTextureSamplers() *
261      * numPrimitiveProcessorTextureSets entries.
262      */
263     void resolveAndGenerateMipMapsForProcessorTextures(
264             const GrPrimitiveProcessor&, const GrPipeline&,
265             const GrTextureProxy* const primitiveProcessorTextures[],
266             int numPrimitiveProcessorTextureSets);
267 
268     // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set.
269     // willDrawPoints must be true if point primitives will be rendered after setting the GL state.
270     // If DynamicStateArrays is not null then dynamicStateArraysLength is the number of dynamic
271     // state entries in each array.
272     bool flushGLState(GrRenderTarget*, GrSurfaceOrigin, const GrPrimitiveProcessor&,
273                       const GrPipeline&, const GrPipeline::FixedDynamicState*,
274                       const GrPipeline::DynamicStateArrays*, int dynamicStateArraysLength,
275                       bool willDrawPoints);
276 
277     void flushProgram(sk_sp<GrGLProgram>);
278 
279     // Version for programs that aren't GrGLProgram.
280     void flushProgram(GrGLuint);
281 
282     // Sets up vertex/instance attribute pointers and strides.
283     void setupGeometry(const GrBuffer* indexBuffer,
284                        const GrBuffer* vertexBuffer,
285                        int baseVertex,
286                        const GrBuffer* instanceBuffer,
287                        int baseInstance,
288                        GrPrimitiveRestart);
289 
290     void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
291 
292     void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
293                        GrFlushFlags flags, bool insertedSemaphores,
294                        GrGpuFinishedProc finishedProc,
295                        GrGpuFinishedContext finishedContext) override;
296 
297     bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
298                            GrSurface* src, GrSurfaceOrigin srcOrigin,
299                            const SkIRect& srcRect, const SkIPoint& dstPoint);
300     void copySurfaceAsCopyTexSubImage(GrSurface* dst, GrSurfaceOrigin dstOrigin,
301                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
302                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
303     bool copySurfaceAsBlitFramebuffer(GrSurface* dst, GrSurfaceOrigin dstOrigin,
304                                       GrSurface* src, GrSurfaceOrigin srcOrigin,
305                                       const SkIRect& srcRect, const SkIPoint& dstPoint);
306 
307     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
308 
309     class ProgramCache : public ::SkNoncopyable {
310     public:
311         ProgramCache(GrGLGpu* gpu);
312         ~ProgramCache();
313 
314         void abandon();
315         GrGLProgram* refProgram(GrGLGpu*, GrRenderTarget*, GrSurfaceOrigin,
316                                 const GrPrimitiveProcessor&,
317                                 const GrTextureProxy* const primProcProxies[],
318                                 const GrPipeline&, bool hasPointSize);
319 
320     private:
321         // We may actually have kMaxEntries+1 shaders in the GL context because we create a new
322         // shader before evicting from the cache.
323         static const int kMaxEntries = 128;
324 
325         struct Entry;
326 
327         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
328         // of the index of where it should be inserted.
329         int search(const GrProgramDesc& desc) const;
330 
331         struct DescHash {
operatorDescHash332             uint32_t operator()(const GrProgramDesc& desc) const {
333                 return SkOpts::hash_fn(desc.asKey(), desc.keyLength(), 0);
334             }
335         };
336 
337         SkLRUCache<GrProgramDesc, std::unique_ptr<Entry>, DescHash> fMap;
338 
339         GrGLGpu*                    fGpu;
340 #ifdef PROGRAM_CACHE_STATS
341         int                         fTotalRequests;
342         int                         fCacheMisses;
343         int                         fHashMisses; // cache hit but hash table missed
344 #endif
345     };
346 
347     void flushColorWrite(bool writeColor);
348     void flushClearColor(GrGLfloat r, GrGLfloat g, GrGLfloat b, GrGLfloat a);
349 
350     // flushes the scissor. see the note on flushBoundTextureAndParams about
351     // flushing the scissor after that function is called.
352     void flushScissor(const GrScissorState&,
353                       const GrGLIRect& rtViewport,
354                       GrSurfaceOrigin rtOrigin);
355 
356     // disables the scissor
357     void disableScissor();
358 
359     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*, GrSurfaceOrigin);
360     void disableWindowRectangles();
361 
numTextureUnits()362     int numTextureUnits() const { return this->caps()->shaderCaps()->maxFragmentSamplers(); }
363 
364     // Binds a texture to a target on the "scratch" texture unit to use for texture operations
365     // other than usual draw flow (i.e. a GrGLProgram derived from a GrPipeline used to draw
366     // GrMesh). It ensures that such operations don't negatively interact with draws.
367     // The active texture unit and the binding for 'target' will change.
368     void bindTextureToScratchUnit(GrGLenum target, GrGLint textureID);
369 
370     // The passed bounds contains the render target's color values that will subsequently be
371     // written.
372     void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
373     // This version has an implicit bounds of the entire render target.
374     void flushRenderTarget(GrGLRenderTarget*);
375     // This version can be used when the render target's colors will not be written.
376     void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
377 
378     // Need not be called if flushRenderTarget is used.
379     void flushViewport(const GrGLIRect&);
380 
381     void flushStencil(const GrStencilSettings&);
382     void disableStencil();
383 
384     // rt is used only if useHWAA is true.
385     void flushHWAAState(GrRenderTarget* rt, bool useHWAA);
386 
387     void flushFramebufferSRGB(bool enable);
388 
389     // helper for onCreateTexture and writeTexturePixels
390     enum UploadType {
391         kNewTexture_UploadType,   // we are creating a new texture
392         kWrite_UploadType,        // we are using TexSubImage2D to copy data to an existing texture
393     };
394     bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight, GrGLenum target,
395                        UploadType uploadType, int left, int top, int width, int height,
396                        GrPixelConfig dataConfig, const GrMipLevel texels[], int mipLevelCount,
397                        GrMipMapsStatus* mipMapsStatus = nullptr);
398 
399     // helper for onCreateCompressedTexture. Compressed textures are read-only so we
400     // only use this to populate a new texture.
401     bool uploadCompressedTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
402                                  GrGLenum target, GrPixelConfig dataConfig,
403                                  const GrMipLevel texels[], int mipLevelCount,
404                                  GrMipMapsStatus* mipMapsStatus = nullptr);
405 
406     bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
407                                    GrGLRenderTarget::IDDesc*);
408 
409     enum TempFBOTarget {
410         kSrc_TempFBOTarget,
411         kDst_TempFBOTarget
412     };
413 
414     // Binds a surface as a FBO for copying, reading, or clearing. If the surface already owns an
415     // FBO ID then that ID is bound. If not the surface is temporarily bound to a FBO and that FBO
416     // is bound. This must be paired with a call to unbindSurfaceFBOForPixelOps().
417     void bindSurfaceFBOForPixelOps(GrSurface* surface, GrGLenum fboTarget, GrGLIRect* viewport,
418                                    TempFBOTarget tempFBOTarget);
419 
420     // Must be called if bindSurfaceFBOForPixelOps was used to bind a surface for copying.
421     void unbindTextureFBOForPixelOps(GrGLenum fboTarget, GrSurface* surface);
422 
423 #ifdef SK_ENABLE_DUMP_GPU
424     void onDumpJSON(SkJSONWriter*) const override;
425 #endif
426 
427     bool createCopyProgram(GrTexture* srcTexture);
428     bool createMipmapProgram(int progIdx);
429 
430     std::unique_ptr<GrGLContext> fGLContext;
431 
432     // GL program-related state
433     ProgramCache*               fProgramCache;
434 
435     ///////////////////////////////////////////////////////////////////////////
436     ///@name Caching of GL State
437     ///@{
438     int                         fHWActiveTextureUnitIdx;
439 
440     GrGLuint                    fHWProgramID;
441     sk_sp<GrGLProgram>          fHWProgram;
442 
443     enum TriState {
444         kNo_TriState,
445         kYes_TriState,
446         kUnknown_TriState
447     };
448 
449     GrGLuint                    fTempSrcFBOID;
450     GrGLuint                    fTempDstFBOID;
451 
452     GrGLuint                    fStencilClearFBOID;
453 
454     // last scissor / viewport scissor state seen by the GL.
455     struct {
456         TriState    fEnabled;
457         GrGLIRect   fRect;
invalidate__anon4916a3130108458         void invalidate() {
459             fEnabled = kUnknown_TriState;
460             fRect.invalidate();
461         }
462     } fHWScissorSettings;
463 
464     class {
465     public:
valid()466         bool valid() const { return kInvalidSurfaceOrigin != fRTOrigin; }
invalidate()467         void invalidate() { fRTOrigin = kInvalidSurfaceOrigin; }
knownDisabled()468         bool knownDisabled() const { return this->valid() && !fWindowState.enabled(); }
setDisabled()469         void setDisabled() {
470             fRTOrigin = kTopLeft_GrSurfaceOrigin;
471             fWindowState.setDisabled();
472         }
473 
set(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)474         void set(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
475                  const GrWindowRectsState& windowState) {
476             fRTOrigin = rtOrigin;
477             fViewport = viewport;
478             fWindowState = windowState;
479         }
480 
knownEqualTo(GrSurfaceOrigin rtOrigin,const GrGLIRect & viewport,const GrWindowRectsState & windowState)481         bool knownEqualTo(GrSurfaceOrigin rtOrigin, const GrGLIRect& viewport,
482                           const GrWindowRectsState& windowState) const {
483             if (!this->valid()) {
484                 return false;
485             }
486             if (fWindowState.numWindows() && (fRTOrigin != rtOrigin || fViewport != viewport)) {
487                 return false;
488             }
489             return fWindowState == windowState;
490         }
491 
492     private:
493         enum { kInvalidSurfaceOrigin = -1 };
494 
495         int                  fRTOrigin;
496         GrGLIRect            fViewport;
497         GrWindowRectsState   fWindowState;
498     } fHWWindowRectsState;
499 
500     GrGLIRect                   fHWViewport;
501 
502     /**
503      * Tracks vertex attrib array state.
504      */
505     class HWVertexArrayState {
506     public:
HWVertexArrayState()507         HWVertexArrayState() : fCoreProfileVertexArray(nullptr) { this->invalidate(); }
508 
~HWVertexArrayState()509         ~HWVertexArrayState() { delete fCoreProfileVertexArray; }
510 
invalidate()511         void invalidate() {
512             fBoundVertexArrayIDIsValid = false;
513             fDefaultVertexArrayAttribState.invalidate();
514             if (fCoreProfileVertexArray) {
515                 fCoreProfileVertexArray->invalidateCachedState();
516             }
517         }
518 
notifyVertexArrayDelete(GrGLuint id)519         void notifyVertexArrayDelete(GrGLuint id) {
520             if (fBoundVertexArrayIDIsValid && fBoundVertexArrayID == id) {
521                 // Does implicit bind to 0
522                 fBoundVertexArrayID = 0;
523             }
524         }
525 
setVertexArrayID(GrGLGpu * gpu,GrGLuint arrayID)526         void setVertexArrayID(GrGLGpu* gpu, GrGLuint arrayID) {
527             if (!gpu->glCaps().vertexArrayObjectSupport()) {
528                 SkASSERT(0 == arrayID);
529                 return;
530             }
531             if (!fBoundVertexArrayIDIsValid || arrayID != fBoundVertexArrayID) {
532                 GR_GL_CALL(gpu->glInterface(), BindVertexArray(arrayID));
533                 fBoundVertexArrayIDIsValid = true;
534                 fBoundVertexArrayID = arrayID;
535             }
536         }
537 
538         /**
539          * Binds the vertex array that should be used for internal draws, and returns its attrib
540          * state. This binds the default VAO (ID=zero) unless we are on a core profile, in which
541          * case we use a dummy array instead.
542          *
543          * If an index buffer is privided, it will be bound to the vertex array. Otherwise the
544          * index buffer binding will be left unchanged.
545          *
546          * The returned GrGLAttribArrayState should be used to set vertex attribute arrays.
547          */
548         GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr);
549 
550     private:
551         GrGLuint             fBoundVertexArrayID;
552         bool                 fBoundVertexArrayIDIsValid;
553 
554         // We return a non-const pointer to this from bindArrayAndBuffersToDraw when vertex array 0
555         // is bound. However, this class is internal to GrGLGpu and this object never leaks out of
556         // GrGLGpu.
557         GrGLAttribArrayState fDefaultVertexArrayAttribState;
558 
559         // This is used when we're using a core profile.
560         GrGLVertexArray*     fCoreProfileVertexArray;
561     }                                       fHWVertexArrayState;
562 
563     struct {
564         GrGLenum                fGLTarget;
565         GrGpuResource::UniqueID fBoundBufferUniqueID;
566         bool                    fBufferZeroKnownBound;
567 
invalidate__anon4916a3130308568         void invalidate() {
569             fBoundBufferUniqueID.makeInvalid();
570             fBufferZeroKnownBound = false;
571         }
572     }                                       fHWBufferState[kGrGpuBufferTypeCount];
573 
hwBufferState(GrGpuBufferType type)574     auto* hwBufferState(GrGpuBufferType type) {
575         unsigned typeAsUInt = static_cast<unsigned>(type);
576         SkASSERT(typeAsUInt < SK_ARRAY_COUNT(fHWBufferState));
577         return &fHWBufferState[typeAsUInt];
578     }
579 
580     struct {
581         GrBlendEquation fEquation;
582         GrBlendCoeff    fSrcCoeff;
583         GrBlendCoeff    fDstCoeff;
584         SkPMColor4f     fConstColor;
585         bool            fConstColorValid;
586         TriState        fEnabled;
587 
invalidate__anon4916a3130408588         void invalidate() {
589             fEquation = kIllegal_GrBlendEquation;
590             fSrcCoeff = kIllegal_GrBlendCoeff;
591             fDstCoeff = kIllegal_GrBlendCoeff;
592             fConstColorValid = false;
593             fEnabled = kUnknown_TriState;
594         }
595     }                                       fHWBlendState;
596 
597     TriState                                fMSAAEnabled;
598 
599     GrStencilSettings                       fHWStencilSettings;
600     TriState                                fHWStencilTestEnabled;
601 
602 
603     TriState                                fHWWriteToColor;
604     GrGpuResource::UniqueID                 fHWBoundRenderTargetUniqueID;
605     TriState                                fHWSRGBFramebuffer;
606 
607     class TextureUnitBindings {
608     public:
609         TextureUnitBindings() = default;
610         TextureUnitBindings(const TextureUnitBindings&) = delete;
611         TextureUnitBindings& operator=(const TextureUnitBindings&) = delete;
612 
613         GrGpuResource::UniqueID boundID(GrGLenum target) const;
614         bool hasBeenModified(GrGLenum target) const;
615         void setBoundID(GrGLenum target, GrGpuResource::UniqueID);
616         void invalidateForScratchUse(GrGLenum target);
617         void invalidateAllTargets(bool markUnmodified);
618 
619     private:
620         struct TargetBinding {
621             GrGpuResource::UniqueID fBoundResourceID;
622             bool fHasBeenModified = false;
623         };
624         TargetBinding fTargetBindings[3];
625     };
626     SkAutoTArray<TextureUnitBindings> fHWTextureUnitBindings;
627 
628     GrGLfloat fHWClearColor[4];
629 
630     GrGLuint fBoundDrawFramebuffer = 0;
631 
632     /** IDs for copy surface program. (3 sampler types) */
633     struct {
634         GrGLuint    fProgram = 0;
635         GrGLint     fTextureUniform = 0;
636         GrGLint     fTexCoordXformUniform = 0;
637         GrGLint     fPosXformUniform = 0;
638     }                                       fCopyPrograms[3];
639     sk_sp<GrGLBuffer>                       fCopyProgramArrayBuffer;
640 
641     /** IDs for texture mipmap program. (4 filter configurations) */
642     struct {
643         GrGLuint    fProgram = 0;
644         GrGLint     fTextureUniform = 0;
645         GrGLint     fTexCoordXformUniform = 0;
646     }                                       fMipmapPrograms[4];
647     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
648 
649     static int TextureToCopyProgramIdx(GrTexture* texture);
650 
TextureSizeToMipmapProgramIdx(int width,int height)651     static int TextureSizeToMipmapProgramIdx(int width, int height) {
652         const bool wide = (width > 1) && SkToBool(width & 0x1);
653         const bool tall = (height > 1) && SkToBool(height & 0x1);
654         return (wide ? 0x2 : 0x0) | (tall ? 0x1 : 0x0);
655     }
656 
657     GrPrimitiveType fLastPrimitiveType;
658 
659     class SamplerObjectCache;
660     std::unique_ptr<SamplerObjectCache> fSamplerObjectCache;
661 
662     std::unique_ptr<GrGLGpuRTCommandBuffer>      fCachedRTCommandBuffer;
663     std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer;
664 
665     friend class GrGLPathRendering; // For accessing setTextureUnit.
666 
667     typedef GrGpu INHERITED;
668 };
669 
670 #endif
671