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