• 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 #include "GrContext.h"
9 #include "GrGLTexture.h"
10 #include "GrGLGpu.h"
11 #include "GrResourceProvider.h"
12 #include "GrSemaphore.h"
13 #include "GrShaderCaps.h"
14 #include "SkMakeUnique.h"
15 #include "SkTraceMemoryDump.h"
16 
17 #define GPUGL static_cast<GrGLGpu*>(this->getGpu())
18 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
19 
sampler_type(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config,const GrGLGpu * gpu)20 static inline GrSLType sampler_type(const GrGLTexture::IDDesc& idDesc, GrPixelConfig config,
21                                     const GrGLGpu* gpu) {
22     if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
23         SkASSERT(gpu->caps()->shaderCaps()->externalTextureSupport());
24         SkASSERT(!GrPixelConfigIsSint(config));
25         return kTextureExternalSampler_GrSLType;
26     } else if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE) {
27         SkASSERT(gpu->glCaps().rectangleTextureSupport());
28         SkASSERT(!GrPixelConfigIsSint(config));
29         return kTexture2DRectSampler_GrSLType;
30     } else if (GrPixelConfigIsSint(config)) {
31         return kITexture2DSampler_GrSLType;
32     } else {
33         SkASSERT(idDesc.fInfo.fTarget == GR_GL_TEXTURE_2D);
34         return kTexture2DSampler_GrSLType;
35     }
36 }
37 
highest_filter_mode(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config)38 static inline GrSamplerParams::FilterMode highest_filter_mode(const GrGLTexture::IDDesc& idDesc,
39                                                               GrPixelConfig config) {
40     if (GrPixelConfigIsSint(config)) {
41         // Integer textures in GL can use GL_NEAREST_MIPMAP_NEAREST. This is a mode we don't support
42         // and don't currently have a use for.
43         return GrSamplerParams::kNone_FilterMode;
44     }
45     if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE ||
46         idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
47         return GrSamplerParams::kBilerp_FilterMode;
48     }
49     return GrSamplerParams::kMipMap_FilterMode;
50 }
51 
52 // Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrGLTexture(GrGLGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const IDDesc & idDesc)53 GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
54                          const IDDesc& idDesc)
55     : GrSurface(gpu, desc)
56     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
57                 highest_filter_mode(idDesc, desc.fConfig), false) {
58     this->init(desc, idDesc);
59     this->registerWithCache(budgeted);
60 }
61 
GrGLTexture(GrGLGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const IDDesc & idDesc,bool wasMipMapDataProvided)62 GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
63                          const IDDesc& idDesc,
64                          bool wasMipMapDataProvided)
65     : GrSurface(gpu, desc)
66     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
67                 highest_filter_mode(idDesc, desc.fConfig),
68                 wasMipMapDataProvided) {
69     this->init(desc, idDesc);
70     this->registerWithCache(budgeted);
71 }
72 
GrGLTexture(GrGLGpu * gpu,Wrapped,const GrSurfaceDesc & desc,const IDDesc & idDesc)73 GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc, const IDDesc& idDesc)
74     : GrSurface(gpu, desc)
75     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
76                 highest_filter_mode(idDesc, desc.fConfig), false) {
77     this->init(desc, idDesc);
78     this->registerWithCacheWrapped();
79 }
80 
GrGLTexture(GrGLGpu * gpu,const GrSurfaceDesc & desc,const IDDesc & idDesc,bool wasMipMapDataProvided)81 GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
82                          bool wasMipMapDataProvided)
83     : GrSurface(gpu, desc)
84     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
85                 highest_filter_mode(idDesc, desc.fConfig),
86                 wasMipMapDataProvided) {
87     this->init(desc, idDesc);
88 }
89 
init(const GrSurfaceDesc & desc,const IDDesc & idDesc)90 void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
91     SkASSERT(0 != idDesc.fInfo.fID);
92     fTexParams.invalidate();
93     fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
94     fInfo = idDesc.fInfo;
95     fTextureIDOwnership = idDesc.fOwnership;
96 }
97 
onRelease()98 void GrGLTexture::onRelease() {
99     if (fInfo.fID) {
100         if (GrBackendObjectOwnership::kBorrowed != fTextureIDOwnership) {
101             GL_CALL(DeleteTextures(1, &fInfo.fID));
102         }
103         fInfo.fID = 0;
104     }
105     INHERITED::onRelease();
106 }
107 
onAbandon()108 void GrGLTexture::onAbandon() {
109     fInfo.fTarget = 0;
110     fInfo.fID = 0;
111     INHERITED::onAbandon();
112 }
113 
getTextureHandle() const114 GrBackendObject GrGLTexture::getTextureHandle() const {
115     return reinterpret_cast<GrBackendObject>(&fInfo);
116 }
117 
detachBackendTexture()118 std::unique_ptr<GrExternalTextureData> GrGLTexture::detachBackendTexture() {
119     // Flush any pending writes to this texture
120     this->getContext()->prepareSurfaceForExternalIO(this);
121 
122     // Set up a semaphore to be signaled once the data is ready, and flush GL
123     sk_sp<GrSemaphore> semaphore = this->getContext()->resourceProvider()->makeSemaphore();
124     this->getGpu()->insertSemaphore(semaphore);
125     this->getGpu()->flush();
126 
127     // Make a copy of our GL-specific information
128     auto data = skstd::make_unique<GrGLExternalTextureData>(fInfo, std::move(semaphore),
129                                                             this->getContext());
130 
131     // Ensure the cache can't reach this texture anymore
132     this->detachFromCache();
133 
134     // Detach from the GL object, so we don't use it (or try to delete it when we're freed)
135     fInfo.fTarget = 0;
136     fInfo.fID = 0;
137 
138     return std::move(data);
139 }
140 
setMemoryBacking(SkTraceMemoryDump * traceMemoryDump,const SkString & dumpName) const141 void GrGLTexture::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
142                                    const SkString& dumpName) const {
143     SkString texture_id;
144     texture_id.appendU32(this->textureID());
145     traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
146                                       texture_id.c_str());
147 }
148 
MakeWrapped(GrGLGpu * gpu,const GrSurfaceDesc & desc,const IDDesc & idDesc)149 sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
150                                             const IDDesc& idDesc) {
151     return sk_sp<GrGLTexture>(new GrGLTexture(gpu, kWrapped, desc, idDesc));
152 }
153 
154