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 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 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. 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 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 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 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 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 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 107 void GrGLTexture::onAbandon() { 108 fInfo.fTarget = 0; 109 fInfo.fID = 0; 110 this->invokeReleaseProc(); 111 INHERITED::onAbandon(); 112 } 113 114 GrBackendObject GrGLTexture::getTextureHandle() const { 115 return reinterpret_cast<GrBackendObject>(&fInfo); 116 } 117 118 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 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