• 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 "GrGLTexture.h"
9 #include "GrGLGpu.h"
10 #include "GrSemaphore.h"
11 #include "GrShaderCaps.h"
12 #include "GrTexturePriv.h"
13 #include "SkTraceMemoryDump.h"
14 
15 #define GPUGL static_cast<GrGLGpu*>(this->getGpu())
16 #define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
17 
sampler_type(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config,const GrGLGpu * gpu)18 static inline GrSLType sampler_type(const GrGLTexture::IDDesc& idDesc, GrPixelConfig config,
19                                     const GrGLGpu* gpu) {
20     if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
21         SkASSERT(gpu->caps()->shaderCaps()->externalTextureSupport());
22         SkASSERT(!GrPixelConfigIsSint(config));
23         return kTextureExternalSampler_GrSLType;
24     } else if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE) {
25         SkASSERT(gpu->glCaps().rectangleTextureSupport());
26         SkASSERT(!GrPixelConfigIsSint(config));
27         return kTexture2DRectSampler_GrSLType;
28     } else if (GrPixelConfigIsSint(config)) {
29         return kITexture2DSampler_GrSLType;
30     } else {
31         SkASSERT(idDesc.fInfo.fTarget == GR_GL_TEXTURE_2D);
32         return kTexture2DSampler_GrSLType;
33     }
34 }
35 
36 // This method parallels GrTextureProxy::highestFilterMode
highest_filter_mode(const GrGLTexture::IDDesc & idDesc,GrPixelConfig config)37 static inline GrSamplerState::Filter highest_filter_mode(const GrGLTexture::IDDesc& idDesc,
38                                                          GrPixelConfig config) {
39     if (GrPixelConfigIsSint(config)) {
40         // Integer textures in GL can use GL_NEAREST_MIPMAP_NEAREST. This is a mode we don't support
41         // and don't currently have a use for.
42         return GrSamplerState::Filter::kNearest;
43     }
44     if (idDesc.fInfo.fTarget == GR_GL_TEXTURE_RECTANGLE ||
45         idDesc.fInfo.fTarget == GR_GL_TEXTURE_EXTERNAL) {
46         return GrSamplerState::Filter::kBilerp;
47     }
48     return GrSamplerState::Filter::kMipMap;
49 }
50 
51 // 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,GrMipMapsStatus mipMapsStatus)52 GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
53                          const IDDesc& idDesc, GrMipMapsStatus mipMapsStatus)
54     : GrSurface(gpu, desc)
55     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
56                 highest_filter_mode(idDesc, desc.fConfig), mipMapsStatus) {
57     this->init(desc, idDesc);
58     this->registerWithCache(budgeted);
59 }
60 
GrGLTexture(GrGLGpu * gpu,Wrapped,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const IDDesc & idDesc)61 GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc,
62                          GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc)
63     : GrSurface(gpu, desc)
64     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
65                 highest_filter_mode(idDesc, desc.fConfig), mipMapsStatus) {
66     this->init(desc, idDesc);
67     this->registerWithCacheWrapped();
68 }
69 
GrGLTexture(GrGLGpu * gpu,const GrSurfaceDesc & desc,const IDDesc & idDesc,GrMipMapsStatus mipMapsStatus)70 GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
71                          GrMipMapsStatus mipMapsStatus)
72     : GrSurface(gpu, desc)
73     , INHERITED(gpu, desc, sampler_type(idDesc, desc.fConfig, gpu),
74                 highest_filter_mode(idDesc, desc.fConfig), mipMapsStatus) {
75     this->init(desc, idDesc);
76 }
77 
init(const GrSurfaceDesc & desc,const IDDesc & idDesc)78 void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
79     SkASSERT(0 != idDesc.fInfo.fID);
80     SkASSERT(0 != idDesc.fInfo.fFormat);
81     fTexParams.invalidate();
82     fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
83     fInfo = idDesc.fInfo;
84     fTextureIDOwnership = idDesc.fOwnership;
85 }
86 
onRelease()87 void GrGLTexture::onRelease() {
88     if (fInfo.fID) {
89         if (GrBackendObjectOwnership::kBorrowed != fTextureIDOwnership) {
90             GL_CALL(DeleteTextures(1, &fInfo.fID));
91         }
92         fInfo.fID = 0;
93     }
94     this->invokeReleaseProc();
95     INHERITED::onRelease();
96 }
97 
onAbandon()98 void GrGLTexture::onAbandon() {
99     fInfo.fTarget = 0;
100     fInfo.fID = 0;
101     this->invokeReleaseProc();
102     INHERITED::onAbandon();
103 }
104 
getTextureHandle() const105 GrBackendObject GrGLTexture::getTextureHandle() const {
106     return reinterpret_cast<GrBackendObject>(&fInfo);
107 }
108 
getBackendTexture() const109 GrBackendTexture GrGLTexture::getBackendTexture() const {
110     return GrBackendTexture(this->width(), this->height(), this->texturePriv().mipMapped(), fInfo);
111 }
112 
setMemoryBacking(SkTraceMemoryDump * traceMemoryDump,const SkString & dumpName) const113 void GrGLTexture::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
114                                    const SkString& dumpName) const {
115     SkString texture_id;
116     texture_id.appendU32(this->textureID());
117     traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
118                                       texture_id.c_str());
119 }
120 
MakeWrapped(GrGLGpu * gpu,const GrSurfaceDesc & desc,GrMipMapsStatus mipMapsStatus,const IDDesc & idDesc)121 sk_sp<GrGLTexture> GrGLTexture::MakeWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
122                                             GrMipMapsStatus mipMapsStatus, const IDDesc& idDesc) {
123     return sk_sp<GrGLTexture>(new GrGLTexture(gpu, kWrapped, desc, mipMapsStatus, idDesc));
124 }
125 
onStealBackendTexture(GrBackendTexture * backendTexture,SkImage::BackendTextureReleaseProc * releaseProc)126 bool GrGLTexture::onStealBackendTexture(GrBackendTexture* backendTexture,
127                                         SkImage::BackendTextureReleaseProc* releaseProc) {
128     *backendTexture = GrBackendTexture(width(), height(), config(), fInfo);
129     // Set the release proc to a no-op function. GL doesn't require any special cleanup.
130     *releaseProc = [](GrBackendTexture){};
131 
132     // It's important that we only abandon this texture's objects, not subclass objects such as
133     // those held by GrGLTextureRenderTarget. Those objects are not being stolen and need to be
134     // cleaned up by us.
135     this->GrGLTexture::onAbandon();
136     return true;
137 }
138