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 
9 #ifndef GrGLTexture_DEFINED
10 #define GrGLTexture_DEFINED
11 
12 #include "GrGpu.h"
13 #include "GrTexture.h"
14 #include "GrGLUtil.h"
15 
16 class GrGLGpu;
17 
18 class GrGLTexture : public GrTexture {
19 public:
20     // Texture state that overlaps with sampler object state. We don't need to track this if we
21     // are using sampler objects.
22     struct SamplerParams {
23         // These are the OpenGL defaults.
24         GrGLenum fMinFilter = GR_GL_NEAREST_MIPMAP_LINEAR;
25         GrGLenum fMagFilter = GR_GL_LINEAR;
26         GrGLenum fWrapS = GR_GL_REPEAT;
27         GrGLenum fWrapT = GR_GL_REPEAT;
28         GrGLfloat fMinLOD = -1000.f;
29         GrGLfloat fMaxLOD = 1000.f;
30         // We always want the border color to be transparent black, so no need to store 4 floats.
31         // Just track if it's been invalidated and no longer the default
32         bool fBorderColorInvalid = false;
33 
invalidateSamplerParams34         void invalidate() {
35             fMinFilter = ~0U;
36             fMagFilter = ~0U;
37             fWrapS = ~0U;
38             fWrapT = ~0U;
39             fMinLOD = SK_ScalarNaN;
40             fMaxLOD = SK_ScalarNaN;
41             fBorderColorInvalid = true;
42         }
43     };
44 
45     // Texture state that does not overlap with sampler object state.
46     struct NonSamplerParams {
47         // These are the OpenGL defaults.
48         uint32_t fSwizzleKey = GrSwizzle::RGBA().asKey();
49         GrGLint fBaseMipMapLevel = 0;
50         GrGLint fMaxMipMapLevel = 1000;
invalidateNonSamplerParams51         void invalidate() {
52             fSwizzleKey = ~0U;
53             fBaseMipMapLevel = ~0;
54             fMaxMipMapLevel = ~0;
55         }
56     };
57 
58     struct IDDesc {
59         GrGLTextureInfo             fInfo;
60         GrBackendObjectOwnership    fOwnership;
61     };
62 
63     static GrTextureType TextureTypeFromTarget(GrGLenum textureTarget);
64 
65     GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&, GrMipMapsStatus);
66 
~GrGLTexture()67     ~GrGLTexture() override {
68         // check that invokeReleaseProc has been called (if needed)
69         SkASSERT(!fReleaseHelper);
70     }
71 
72     GrBackendTexture getBackendTexture() const override;
73 
74     GrBackendFormat backendFormat() const override;
75 
textureParamsModified()76     void textureParamsModified() override {
77         fSamplerParams.invalidate();
78         fNonSamplerParams.invalidate();
79     }
80 
setRelease(sk_sp<GrReleaseProcHelper> releaseHelper)81     void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
82         fReleaseHelper = std::move(releaseHelper);
83     }
84 
setIdleProc(IdleProc proc,void * context)85     void setIdleProc(IdleProc proc, void* context) override {
86         fIdleProc = proc;
87         fIdleProcContext = context;
88     }
idleContext()89     void* idleContext() const override { return fIdleProcContext; }
90 
91     // These functions are used to track the texture parameters associated with the texture.
getCachedParamsTimestamp()92     GrGpu::ResetTimestamp getCachedParamsTimestamp() const { return fParamsTimestamp; }
getCachedSamplerParams()93     const SamplerParams& getCachedSamplerParams() const { return fSamplerParams; }
getCachedNonSamplerParams()94     const NonSamplerParams& getCachedNonSamplerParams() const { return fNonSamplerParams; }
95 
setCachedParams(const SamplerParams * samplerParams,const NonSamplerParams & nonSamplerParams,GrGpu::ResetTimestamp currTimestamp)96     void setCachedParams(const SamplerParams* samplerParams,
97                          const NonSamplerParams& nonSamplerParams,
98                          GrGpu::ResetTimestamp currTimestamp) {
99         if (samplerParams) {
100             fSamplerParams = *samplerParams;
101         }
102         fNonSamplerParams = nonSamplerParams;
103         fParamsTimestamp = currTimestamp;
104     }
105 
textureID()106     GrGLuint textureID() const { return fID; }
107 
108     GrGLenum target() const;
109 
hasBaseLevelBeenBoundToFBO()110     bool hasBaseLevelBeenBoundToFBO() const { return fBaseLevelHasBeenBoundToFBO; }
baseLevelWasBoundToFBO()111     void baseLevelWasBoundToFBO() { fBaseLevelHasBeenBoundToFBO = true; }
112 
113     static sk_sp<GrGLTexture> MakeWrapped(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus,
114                                           const IDDesc&, GrWrapCacheable, GrIOType);
115 
116     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
117 
118 protected:
119     // Constructor for subclasses.
120     GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrMipMapsStatus);
121 
122     // Constructor for instances wrapping backend objects.
123     GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, GrMipMapsStatus, const IDDesc&, GrWrapCacheable,
124                 GrIOType);
125 
126     void init(const GrSurfaceDesc&, const IDDesc&);
127 
128     void onAbandon() override;
129     void onRelease() override;
130 
131     bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override;
132 
133 private:
invokeReleaseProc()134     void invokeReleaseProc() {
135         // Depending on the ref count of fReleaseHelper this may or may not actually trigger the
136         // ReleaseProc to be called.
137         fReleaseHelper.reset();
138     }
139 
removedLastRefOrPendingIO()140     void removedLastRefOrPendingIO() override {
141         if (fIdleProc) {
142             fIdleProc(fIdleProcContext);
143             fIdleProc = nullptr;
144             fIdleProcContext = nullptr;
145         }
146     }
147 
148     SamplerParams fSamplerParams;
149     NonSamplerParams fNonSamplerParams;
150     GrGpu::ResetTimestamp fParamsTimestamp;
151     sk_sp<GrReleaseProcHelper> fReleaseHelper;
152     IdleProc* fIdleProc = nullptr;
153     void* fIdleProcContext = nullptr;
154     GrGLuint fID;
155     GrGLenum fFormat;
156     GrBackendObjectOwnership fTextureIDOwnership;
157     bool fBaseLevelHasBeenBoundToFBO = false;
158 
159     typedef GrTexture INHERITED;
160 };
161 
162 #endif
163