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