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 "GrGLTexture.h"
9 #include "GrGLGpu.h"
10 #include "GrSemaphore.h"
11 #include "GrShaderCaps.h"
12 #include "SkTraceMemoryDump.h"
13
14 #define GPUGL static_cast<GrGLGpu*>(this->getGpu())
15 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
16
sampler_type(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config,const GrGLGpu * gpu)17 static inline GrSLType sampler_type(const GrGLTexture::IDDesc& idDesc, GrPixelConfig config,
18 const GrGLGpu* gpu) {
19 if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
20 SkASSERT(gpu->caps()->shaderCaps()->externalTextureSupport());
21 SkASSERT(!GrPixelConfigIsSint(config));
22 return kTextureExternalSampler_GrSLType;
23 } else if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE) {
24 SkASSERT(gpu->glCaps().rectangleTextureSupport());
25 SkASSERT(!GrPixelConfigIsSint(config));
26 return kTexture2DRectSampler_GrSLType;
27 } else if (GrPixelConfigIsSint(config)) {
28 return kITexture2DSampler_GrSLType;
29 } else {
30 SkASSERT(idDesc.fInfo.fTarget == GR_GL_TEXTURE_2D);
31 return kTexture2DSampler_GrSLType;
32 }
33 }
34
35 // This method parallels GrTextureProxy::highestFilterMode
highest_filter_mode(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config)36 static inline GrSamplerParams::FilterMode highest_filter_mode(const GrGLTexture::IDDesc& idDesc,
37 GrPixelConfig config) {
38 if (GrPixelConfigIsSint(config)) {
39 // Integer textures in GL can use GL_NEAREST_MIPMAP_NEAREST. This is a mode we don't support
40 // and don't currently have a use for.
41 return GrSamplerParams::kNone_FilterMode;
42 }
43 if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE ||
44 idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
45 return GrSamplerParams::kBilerp_FilterMode;
46 }
47 return GrSamplerParams::kMipMap_FilterMode;
48 }
49
50 // 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)51 GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
52 const IDDesc& idDesc)
53 : GrSurface(gpu, desc)
54 , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
55 highest_filter_mode(idDesc, desc.fConfig), false) {
56 this->init(desc, idDesc);
57 this->registerWithCache(budgeted);
58 }
59
GrGLTexture(GrGLGpu * gpu,SkBudgeted budgeted,const GrSurfaceDesc & desc,const IDDesc & idDesc,bool wasMipMapDataProvided)60 GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
61 const IDDesc& idDesc,
62 bool wasMipMapDataProvided)
63 : GrSurface(gpu, desc)
64 , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
65 highest_filter_mode(idDesc, desc.fConfig),
66 wasMipMapDataProvided) {
67 this->init(desc, idDesc);
68 this->registerWithCache(budgeted);
69 }
70
GrGLTexture(GrGLGpu * gpu,Wrapped,const GrSurfaceDesc & desc,const IDDesc & idDesc)71 GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc, const IDDesc& idDesc)
72 : GrSurface(gpu, desc)
73 , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
74 highest_filter_mode(idDesc, desc.fConfig), false) {
75 this->init(desc, idDesc);
76 this->registerWithCacheWrapped();
77 }
78
GrGLTexture(GrGLGpu * gpu,const GrSurfaceDesc & desc,const IDDesc & idDesc,bool wasMipMapDataProvided)79 GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
80 bool wasMipMapDataProvided)
81 : GrSurface(gpu, desc)
82 , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
83 highest_filter_mode(idDesc, desc.fConfig),
84 wasMipMapDataProvided) {
85 this->init(desc, idDesc);
86 }
87
init(const GrSurfaceDesc & desc,const IDDesc & idDesc)88 void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
89 SkASSERT(0 != idDesc.fInfo.fID);
90 fTexParams.invalidate();
91 fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
92 fInfo = idDesc.fInfo;
93 fTextureIDOwnership = idDesc.fOwnership;
94 }
95
onRelease()96 void GrGLTexture::onRelease() {
97 if (fInfo.fID) {
98 if (GrBackendObjectOwnership::kBorrowed != fTextureIDOwnership) {
99 GL_CALL(DeleteTextures(1, &fInfo.fID));
100 }
101 fInfo.fID = 0;
102 }
103 this->invokeReleaseProc();
104 INHERITED::onRelease();
105 }
106
onAbandon()107 void GrGLTexture::onAbandon() {
108 fInfo.fTarget = 0;
109 fInfo.fID = 0;
110 this->invokeReleaseProc();
111 INHERITED::onAbandon();
112 }
113
getTextureHandle() const114 GrBackendObject GrGLTexture::getTextureHandle() const {
115 return reinterpret_cast<GrBackendObject>(&fInfo);
116 }
117
setMemoryBacking(SkTraceMemoryDump * traceMemoryDump,const SkString & dumpName) const118 void GrGLTexture::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
119 const SkString& dumpName) const {
120 SkString texture_id;
121 texture_id.appendU32(this->textureID());
122 traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
123 texture_id.c_str());
124 }
125
MakeWrapped(GrGLGpu * gpu,const GrSurfaceDesc & desc,const IDDesc & idDesc)126 sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
127 const IDDesc& idDesc) {
128 return sk_sp<GrGLTexture>(new GrGLTexture(gpu, kWrapped, desc, idDesc));
129 }
130
131