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