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