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