1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // Texture.cpp: Implements the gl::Texture class. [OpenGL ES 2.0.24] section 3.7 page 63.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Config.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/State.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Surface.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ContextImpl.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/GLImplFactory.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/TextureImpl.h"
22*8975f5c5SAndroid Build Coastguard Worker
23*8975f5c5SAndroid Build Coastguard Worker namespace gl
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Worker namespace
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker constexpr angle::SubjectIndex kBufferSubjectIndex = 2;
29*8975f5c5SAndroid Build Coastguard Worker static_assert(kBufferSubjectIndex != rx::kTextureImageImplObserverMessageIndex, "Index collision");
30*8975f5c5SAndroid Build Coastguard Worker static_assert(kBufferSubjectIndex != rx::kTextureImageSiblingMessageIndex, "Index collision");
31*8975f5c5SAndroid Build Coastguard Worker
IsPointSampled(const SamplerState & samplerState)32*8975f5c5SAndroid Build Coastguard Worker bool IsPointSampled(const SamplerState &samplerState)
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker return (samplerState.getMagFilter() == GL_NEAREST &&
35*8975f5c5SAndroid Build Coastguard Worker (samplerState.getMinFilter() == GL_NEAREST ||
36*8975f5c5SAndroid Build Coastguard Worker samplerState.getMinFilter() == GL_NEAREST_MIPMAP_NEAREST));
37*8975f5c5SAndroid Build Coastguard Worker }
38*8975f5c5SAndroid Build Coastguard Worker
GetImageDescIndex(TextureTarget target,size_t level)39*8975f5c5SAndroid Build Coastguard Worker size_t GetImageDescIndex(TextureTarget target, size_t level)
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker return IsCubeMapFaceTarget(target) ? (level * 6 + CubeMapTextureTargetToFaceIndex(target))
42*8975f5c5SAndroid Build Coastguard Worker : level;
43*8975f5c5SAndroid Build Coastguard Worker }
44*8975f5c5SAndroid Build Coastguard Worker
DetermineInitState(const Context * context,Buffer * unpackBuffer,const uint8_t * pixels)45*8975f5c5SAndroid Build Coastguard Worker InitState DetermineInitState(const Context *context, Buffer *unpackBuffer, const uint8_t *pixels)
46*8975f5c5SAndroid Build Coastguard Worker {
47*8975f5c5SAndroid Build Coastguard Worker // Can happen in tests.
48*8975f5c5SAndroid Build Coastguard Worker if (!context || !context->isRobustResourceInitEnabled())
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker return InitState::Initialized;
51*8975f5c5SAndroid Build Coastguard Worker }
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker return (!pixels && !unpackBuffer) ? InitState::MayNeedInit : InitState::Initialized;
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker } // namespace
56*8975f5c5SAndroid Build Coastguard Worker
ConvertToNearestFilterMode(GLenum filterMode)57*8975f5c5SAndroid Build Coastguard Worker GLenum ConvertToNearestFilterMode(GLenum filterMode)
58*8975f5c5SAndroid Build Coastguard Worker {
59*8975f5c5SAndroid Build Coastguard Worker switch (filterMode)
60*8975f5c5SAndroid Build Coastguard Worker {
61*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR:
62*8975f5c5SAndroid Build Coastguard Worker return GL_NEAREST;
63*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_MIPMAP_NEAREST:
64*8975f5c5SAndroid Build Coastguard Worker return GL_NEAREST_MIPMAP_NEAREST;
65*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_MIPMAP_LINEAR:
66*8975f5c5SAndroid Build Coastguard Worker return GL_NEAREST_MIPMAP_LINEAR;
67*8975f5c5SAndroid Build Coastguard Worker default:
68*8975f5c5SAndroid Build Coastguard Worker return filterMode;
69*8975f5c5SAndroid Build Coastguard Worker }
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker
ConvertToNearestMipFilterMode(GLenum filterMode)72*8975f5c5SAndroid Build Coastguard Worker GLenum ConvertToNearestMipFilterMode(GLenum filterMode)
73*8975f5c5SAndroid Build Coastguard Worker {
74*8975f5c5SAndroid Build Coastguard Worker switch (filterMode)
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_MIPMAP_LINEAR:
77*8975f5c5SAndroid Build Coastguard Worker return GL_LINEAR_MIPMAP_NEAREST;
78*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST_MIPMAP_LINEAR:
79*8975f5c5SAndroid Build Coastguard Worker return GL_NEAREST_MIPMAP_NEAREST;
80*8975f5c5SAndroid Build Coastguard Worker default:
81*8975f5c5SAndroid Build Coastguard Worker return filterMode;
82*8975f5c5SAndroid Build Coastguard Worker }
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker
IsMipmapSupported(const TextureType & type)85*8975f5c5SAndroid Build Coastguard Worker bool IsMipmapSupported(const TextureType &type)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker switch (type)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisample:
90*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisampleArray:
91*8975f5c5SAndroid Build Coastguard Worker case TextureType::Buffer:
92*8975f5c5SAndroid Build Coastguard Worker return false;
93*8975f5c5SAndroid Build Coastguard Worker default:
94*8975f5c5SAndroid Build Coastguard Worker return true;
95*8975f5c5SAndroid Build Coastguard Worker }
96*8975f5c5SAndroid Build Coastguard Worker }
97*8975f5c5SAndroid Build Coastguard Worker
SwizzleState()98*8975f5c5SAndroid Build Coastguard Worker SwizzleState::SwizzleState()
99*8975f5c5SAndroid Build Coastguard Worker : swizzleRed(GL_RED), swizzleGreen(GL_GREEN), swizzleBlue(GL_BLUE), swizzleAlpha(GL_ALPHA)
100*8975f5c5SAndroid Build Coastguard Worker {}
101*8975f5c5SAndroid Build Coastguard Worker
SwizzleState(GLenum red,GLenum green,GLenum blue,GLenum alpha)102*8975f5c5SAndroid Build Coastguard Worker SwizzleState::SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha)
103*8975f5c5SAndroid Build Coastguard Worker : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
104*8975f5c5SAndroid Build Coastguard Worker {}
105*8975f5c5SAndroid Build Coastguard Worker
swizzleRequired() const106*8975f5c5SAndroid Build Coastguard Worker bool SwizzleState::swizzleRequired() const
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || swizzleBlue != GL_BLUE ||
109*8975f5c5SAndroid Build Coastguard Worker swizzleAlpha != GL_ALPHA;
110*8975f5c5SAndroid Build Coastguard Worker }
111*8975f5c5SAndroid Build Coastguard Worker
operator ==(const SwizzleState & other) const112*8975f5c5SAndroid Build Coastguard Worker bool SwizzleState::operator==(const SwizzleState &other) const
113*8975f5c5SAndroid Build Coastguard Worker {
114*8975f5c5SAndroid Build Coastguard Worker return swizzleRed == other.swizzleRed && swizzleGreen == other.swizzleGreen &&
115*8975f5c5SAndroid Build Coastguard Worker swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha;
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker
operator !=(const SwizzleState & other) const118*8975f5c5SAndroid Build Coastguard Worker bool SwizzleState::operator!=(const SwizzleState &other) const
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker return !(*this == other);
121*8975f5c5SAndroid Build Coastguard Worker }
122*8975f5c5SAndroid Build Coastguard Worker
TextureState(TextureType type)123*8975f5c5SAndroid Build Coastguard Worker TextureState::TextureState(TextureType type)
124*8975f5c5SAndroid Build Coastguard Worker : mType(type),
125*8975f5c5SAndroid Build Coastguard Worker mSamplerState(SamplerState::CreateDefaultForTarget(type)),
126*8975f5c5SAndroid Build Coastguard Worker mSrgbOverride(SrgbOverride::Default),
127*8975f5c5SAndroid Build Coastguard Worker mBaseLevel(0),
128*8975f5c5SAndroid Build Coastguard Worker mMaxLevel(kInitialMaxLevel),
129*8975f5c5SAndroid Build Coastguard Worker mDepthStencilTextureMode(GL_DEPTH_COMPONENT),
130*8975f5c5SAndroid Build Coastguard Worker mIsInternalIncompleteTexture(false),
131*8975f5c5SAndroid Build Coastguard Worker mHasBeenBoundAsImage(false),
132*8975f5c5SAndroid Build Coastguard Worker mHasBeenBoundAsAttachment(false),
133*8975f5c5SAndroid Build Coastguard Worker mHasBeenBoundToMSRTTFramebuffer(false),
134*8975f5c5SAndroid Build Coastguard Worker mImmutableFormat(false),
135*8975f5c5SAndroid Build Coastguard Worker mImmutableLevels(0),
136*8975f5c5SAndroid Build Coastguard Worker mUsage(GL_NONE),
137*8975f5c5SAndroid Build Coastguard Worker mHasProtectedContent(false),
138*8975f5c5SAndroid Build Coastguard Worker mRenderabilityValidation(true),
139*8975f5c5SAndroid Build Coastguard Worker mTilingMode(gl::TilingMode::Optimal),
140*8975f5c5SAndroid Build Coastguard Worker mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)),
141*8975f5c5SAndroid Build Coastguard Worker mCropRect(0, 0, 0, 0),
142*8975f5c5SAndroid Build Coastguard Worker mGenerateMipmapHint(GL_FALSE),
143*8975f5c5SAndroid Build Coastguard Worker mInitState(InitState::Initialized),
144*8975f5c5SAndroid Build Coastguard Worker mCachedSamplerFormat(SamplerFormat::InvalidEnum),
145*8975f5c5SAndroid Build Coastguard Worker mCachedSamplerCompareMode(GL_NONE),
146*8975f5c5SAndroid Build Coastguard Worker mCachedSamplerFormatValid(false),
147*8975f5c5SAndroid Build Coastguard Worker mCompressionFixedRate(GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT)
148*8975f5c5SAndroid Build Coastguard Worker {}
149*8975f5c5SAndroid Build Coastguard Worker
~TextureState()150*8975f5c5SAndroid Build Coastguard Worker TextureState::~TextureState() {}
151*8975f5c5SAndroid Build Coastguard Worker
swizzleRequired() const152*8975f5c5SAndroid Build Coastguard Worker bool TextureState::swizzleRequired() const
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker return mSwizzleState.swizzleRequired();
155*8975f5c5SAndroid Build Coastguard Worker }
156*8975f5c5SAndroid Build Coastguard Worker
getEffectiveBaseLevel() const157*8975f5c5SAndroid Build Coastguard Worker GLuint TextureState::getEffectiveBaseLevel() const
158*8975f5c5SAndroid Build Coastguard Worker {
159*8975f5c5SAndroid Build Coastguard Worker if (mImmutableFormat)
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10
162*8975f5c5SAndroid Build Coastguard Worker return std::min(mBaseLevel, mImmutableLevels - 1);
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker // Some classes use the effective base level to index arrays with level data. By clamping the
165*8975f5c5SAndroid Build Coastguard Worker // effective base level to max levels these arrays need just one extra item to store properties
166*8975f5c5SAndroid Build Coastguard Worker // that should be returned for all out-of-range base level values, instead of needing special
167*8975f5c5SAndroid Build Coastguard Worker // handling for out-of-range base levels.
168*8975f5c5SAndroid Build Coastguard Worker return std::min(mBaseLevel, static_cast<GLuint>(IMPLEMENTATION_MAX_TEXTURE_LEVELS));
169*8975f5c5SAndroid Build Coastguard Worker }
170*8975f5c5SAndroid Build Coastguard Worker
getEffectiveMaxLevel() const171*8975f5c5SAndroid Build Coastguard Worker GLuint TextureState::getEffectiveMaxLevel() const
172*8975f5c5SAndroid Build Coastguard Worker {
173*8975f5c5SAndroid Build Coastguard Worker if (mImmutableFormat)
174*8975f5c5SAndroid Build Coastguard Worker {
175*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10
176*8975f5c5SAndroid Build Coastguard Worker GLuint clampedMaxLevel = std::max(mMaxLevel, getEffectiveBaseLevel());
177*8975f5c5SAndroid Build Coastguard Worker clampedMaxLevel = std::min(clampedMaxLevel, mImmutableLevels - 1);
178*8975f5c5SAndroid Build Coastguard Worker return clampedMaxLevel;
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker return mMaxLevel;
181*8975f5c5SAndroid Build Coastguard Worker }
182*8975f5c5SAndroid Build Coastguard Worker
getMipmapMaxLevel() const183*8975f5c5SAndroid Build Coastguard Worker GLuint TextureState::getMipmapMaxLevel() const
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
186*8975f5c5SAndroid Build Coastguard Worker GLuint expectedMipLevels = 0;
187*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::_3D)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker const int maxDim = std::max(
190*8975f5c5SAndroid Build Coastguard Worker {baseImageDesc.size.width, baseImageDesc.size.height, baseImageDesc.size.depth});
191*8975f5c5SAndroid Build Coastguard Worker expectedMipLevels = static_cast<GLuint>(log2(maxDim));
192*8975f5c5SAndroid Build Coastguard Worker }
193*8975f5c5SAndroid Build Coastguard Worker else
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker expectedMipLevels = static_cast<GLuint>(
196*8975f5c5SAndroid Build Coastguard Worker log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)));
197*8975f5c5SAndroid Build Coastguard Worker }
198*8975f5c5SAndroid Build Coastguard Worker
199*8975f5c5SAndroid Build Coastguard Worker return std::min<GLuint>(getEffectiveBaseLevel() + expectedMipLevels, getEffectiveMaxLevel());
200*8975f5c5SAndroid Build Coastguard Worker }
201*8975f5c5SAndroid Build Coastguard Worker
setBaseLevel(GLuint baseLevel)202*8975f5c5SAndroid Build Coastguard Worker bool TextureState::setBaseLevel(GLuint baseLevel)
203*8975f5c5SAndroid Build Coastguard Worker {
204*8975f5c5SAndroid Build Coastguard Worker if (mBaseLevel != baseLevel)
205*8975f5c5SAndroid Build Coastguard Worker {
206*8975f5c5SAndroid Build Coastguard Worker mBaseLevel = baseLevel;
207*8975f5c5SAndroid Build Coastguard Worker return true;
208*8975f5c5SAndroid Build Coastguard Worker }
209*8975f5c5SAndroid Build Coastguard Worker return false;
210*8975f5c5SAndroid Build Coastguard Worker }
211*8975f5c5SAndroid Build Coastguard Worker
setMaxLevel(GLuint maxLevel)212*8975f5c5SAndroid Build Coastguard Worker bool TextureState::setMaxLevel(GLuint maxLevel)
213*8975f5c5SAndroid Build Coastguard Worker {
214*8975f5c5SAndroid Build Coastguard Worker if (mMaxLevel != maxLevel)
215*8975f5c5SAndroid Build Coastguard Worker {
216*8975f5c5SAndroid Build Coastguard Worker mMaxLevel = maxLevel;
217*8975f5c5SAndroid Build Coastguard Worker return true;
218*8975f5c5SAndroid Build Coastguard Worker }
219*8975f5c5SAndroid Build Coastguard Worker
220*8975f5c5SAndroid Build Coastguard Worker return false;
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker
223*8975f5c5SAndroid Build Coastguard Worker // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
224*8975f5c5SAndroid Build Coastguard Worker // According to [OpenGL ES 3.0.5] section 3.8.13 Texture Completeness page 160 any
225*8975f5c5SAndroid Build Coastguard Worker // per-level checks begin at the base-level.
226*8975f5c5SAndroid Build Coastguard Worker // For OpenGL ES2 the base level is always zero.
isCubeComplete() const227*8975f5c5SAndroid Build Coastguard Worker bool TextureState::isCubeComplete() const
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker ASSERT(mType == TextureType::CubeMap);
230*8975f5c5SAndroid Build Coastguard Worker
231*8975f5c5SAndroid Build Coastguard Worker angle::EnumIterator<TextureTarget> face = kCubeMapTextureTargetMin;
232*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &baseImageDesc = getImageDesc(*face, getEffectiveBaseLevel());
233*8975f5c5SAndroid Build Coastguard Worker if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height)
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker return false;
236*8975f5c5SAndroid Build Coastguard Worker }
237*8975f5c5SAndroid Build Coastguard Worker
238*8975f5c5SAndroid Build Coastguard Worker ++face;
239*8975f5c5SAndroid Build Coastguard Worker
240*8975f5c5SAndroid Build Coastguard Worker for (; face != kAfterCubeMapTextureTargetMax; ++face)
241*8975f5c5SAndroid Build Coastguard Worker {
242*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &faceImageDesc = getImageDesc(*face, getEffectiveBaseLevel());
243*8975f5c5SAndroid Build Coastguard Worker if (faceImageDesc.size.width != baseImageDesc.size.width ||
244*8975f5c5SAndroid Build Coastguard Worker faceImageDesc.size.height != baseImageDesc.size.height ||
245*8975f5c5SAndroid Build Coastguard Worker !Format::SameSized(faceImageDesc.format, baseImageDesc.format))
246*8975f5c5SAndroid Build Coastguard Worker {
247*8975f5c5SAndroid Build Coastguard Worker return false;
248*8975f5c5SAndroid Build Coastguard Worker }
249*8975f5c5SAndroid Build Coastguard Worker }
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Worker return true;
252*8975f5c5SAndroid Build Coastguard Worker }
253*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelDesc() const254*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &TextureState::getBaseLevelDesc() const
255*8975f5c5SAndroid Build Coastguard Worker {
256*8975f5c5SAndroid Build Coastguard Worker ASSERT(mType != TextureType::CubeMap || isCubeComplete());
257*8975f5c5SAndroid Build Coastguard Worker return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker
getLevelZeroDesc() const260*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &TextureState::getLevelZeroDesc() const
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker ASSERT(mType != TextureType::CubeMap || isCubeComplete());
263*8975f5c5SAndroid Build Coastguard Worker return getImageDesc(getBaseImageTarget(), 0);
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker
setCrop(const Rectangle & rect)266*8975f5c5SAndroid Build Coastguard Worker void TextureState::setCrop(const Rectangle &rect)
267*8975f5c5SAndroid Build Coastguard Worker {
268*8975f5c5SAndroid Build Coastguard Worker mCropRect = rect;
269*8975f5c5SAndroid Build Coastguard Worker }
270*8975f5c5SAndroid Build Coastguard Worker
getCrop() const271*8975f5c5SAndroid Build Coastguard Worker const Rectangle &TextureState::getCrop() const
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker return mCropRect;
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker
setGenerateMipmapHint(GLenum hint)276*8975f5c5SAndroid Build Coastguard Worker void TextureState::setGenerateMipmapHint(GLenum hint)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker mGenerateMipmapHint = hint;
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker
getGenerateMipmapHint() const281*8975f5c5SAndroid Build Coastguard Worker GLenum TextureState::getGenerateMipmapHint() const
282*8975f5c5SAndroid Build Coastguard Worker {
283*8975f5c5SAndroid Build Coastguard Worker return mGenerateMipmapHint;
284*8975f5c5SAndroid Build Coastguard Worker }
285*8975f5c5SAndroid Build Coastguard Worker
computeRequiredSamplerFormat(const SamplerState & samplerState) const286*8975f5c5SAndroid Build Coastguard Worker SamplerFormat TextureState::computeRequiredSamplerFormat(const SamplerState &samplerState) const
287*8975f5c5SAndroid Build Coastguard Worker {
288*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &info =
289*8975f5c5SAndroid Build Coastguard Worker *getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()).format.info;
290*8975f5c5SAndroid Build Coastguard Worker if ((info.format == GL_DEPTH_COMPONENT ||
291*8975f5c5SAndroid Build Coastguard Worker (info.format == GL_DEPTH_STENCIL && mDepthStencilTextureMode == GL_DEPTH_COMPONENT)) &&
292*8975f5c5SAndroid Build Coastguard Worker samplerState.getCompareMode() != GL_NONE)
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::Shadow;
295*8975f5c5SAndroid Build Coastguard Worker }
296*8975f5c5SAndroid Build Coastguard Worker else if (info.format == GL_STENCIL_INDEX ||
297*8975f5c5SAndroid Build Coastguard Worker (info.format == GL_DEPTH_STENCIL && mDepthStencilTextureMode == GL_STENCIL_INDEX))
298*8975f5c5SAndroid Build Coastguard Worker {
299*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::Unsigned;
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker else
302*8975f5c5SAndroid Build Coastguard Worker {
303*8975f5c5SAndroid Build Coastguard Worker switch (info.componentType)
304*8975f5c5SAndroid Build Coastguard Worker {
305*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_NORMALIZED:
306*8975f5c5SAndroid Build Coastguard Worker case GL_SIGNED_NORMALIZED:
307*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
308*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::Float;
309*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
310*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::Signed;
311*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
312*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::Unsigned;
313*8975f5c5SAndroid Build Coastguard Worker default:
314*8975f5c5SAndroid Build Coastguard Worker return SamplerFormat::InvalidEnum;
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker }
317*8975f5c5SAndroid Build Coastguard Worker }
318*8975f5c5SAndroid Build Coastguard Worker
computeSamplerCompleteness(const SamplerState & samplerState,const State & state) const319*8975f5c5SAndroid Build Coastguard Worker bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState,
320*8975f5c5SAndroid Build Coastguard Worker const State &state) const
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker // Buffer textures cannot be incomplete. But if they are, the spec says -
323*8975f5c5SAndroid Build Coastguard Worker //
324*8975f5c5SAndroid Build Coastguard Worker // If no buffer object is bound to the buffer texture,
325*8975f5c5SAndroid Build Coastguard Worker // the results of the texel access are undefined.
326*8975f5c5SAndroid Build Coastguard Worker //
327*8975f5c5SAndroid Build Coastguard Worker // Mark as incomplete so we use the default IncompleteTexture instead
328*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::Buffer)
329*8975f5c5SAndroid Build Coastguard Worker {
330*8975f5c5SAndroid Build Coastguard Worker return mBuffer.get() != nullptr;
331*8975f5c5SAndroid Build Coastguard Worker }
332*8975f5c5SAndroid Build Coastguard Worker
333*8975f5c5SAndroid Build Coastguard Worker // Check for all non-format-based completeness rules
334*8975f5c5SAndroid Build Coastguard Worker if (!computeSamplerCompletenessForCopyImage(samplerState, state))
335*8975f5c5SAndroid Build Coastguard Worker {
336*8975f5c5SAndroid Build Coastguard Worker return false;
337*8975f5c5SAndroid Build Coastguard Worker }
338*8975f5c5SAndroid Build Coastguard Worker
339*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.2, Sections 8.8 and 11.1.3.3
340*8975f5c5SAndroid Build Coastguard Worker // Multisample textures do not have mipmaps and filter state is ignored.
341*8975f5c5SAndroid Build Coastguard Worker if (IsMultisampled(mType))
342*8975f5c5SAndroid Build Coastguard Worker {
343*8975f5c5SAndroid Build Coastguard Worker return true;
344*8975f5c5SAndroid Build Coastguard Worker }
345*8975f5c5SAndroid Build Coastguard Worker
346*8975f5c5SAndroid Build Coastguard Worker // OpenGL ES 3.2, Section 8.17
347*8975f5c5SAndroid Build Coastguard Worker // A texture is complete unless either the magnification filter is not NEAREST,
348*8975f5c5SAndroid Build Coastguard Worker // or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST; and any of
349*8975f5c5SAndroid Build Coastguard Worker if (IsPointSampled(samplerState))
350*8975f5c5SAndroid Build Coastguard Worker {
351*8975f5c5SAndroid Build Coastguard Worker return true;
352*8975f5c5SAndroid Build Coastguard Worker }
353*8975f5c5SAndroid Build Coastguard Worker
354*8975f5c5SAndroid Build Coastguard Worker const InternalFormat *info =
355*8975f5c5SAndroid Build Coastguard Worker getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()).format.info;
356*8975f5c5SAndroid Build Coastguard Worker
357*8975f5c5SAndroid Build Coastguard Worker // The effective internal format specified for the texture images
358*8975f5c5SAndroid Build Coastguard Worker // is a sized internal color format that is not texture-filterable.
359*8975f5c5SAndroid Build Coastguard Worker if (!info->isDepthOrStencil())
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker return info->filterSupport(state.getClientVersion(), state.getExtensions());
362*8975f5c5SAndroid Build Coastguard Worker }
363*8975f5c5SAndroid Build Coastguard Worker
364*8975f5c5SAndroid Build Coastguard Worker // The effective internal format specified for the texture images
365*8975f5c5SAndroid Build Coastguard Worker // is a sized internal depth or depth and stencil format (see table 8.11),
366*8975f5c5SAndroid Build Coastguard Worker // and the value of TEXTURE_COMPARE_MODE is NONE.
367*8975f5c5SAndroid Build Coastguard Worker if (info->depthBits > 0 && samplerState.getCompareMode() == GL_NONE)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker // Note: we restrict this validation to sized types. For the OES_depth_textures
370*8975f5c5SAndroid Build Coastguard Worker // extension, due to some underspecification problems, we must allow linear filtering
371*8975f5c5SAndroid Build Coastguard Worker // for legacy compatibility with WebGL 1.0.
372*8975f5c5SAndroid Build Coastguard Worker // See http://crbug.com/649200
373*8975f5c5SAndroid Build Coastguard Worker if (state.getClientMajorVersion() >= 3 && info->sized)
374*8975f5c5SAndroid Build Coastguard Worker {
375*8975f5c5SAndroid Build Coastguard Worker return false;
376*8975f5c5SAndroid Build Coastguard Worker }
377*8975f5c5SAndroid Build Coastguard Worker }
378*8975f5c5SAndroid Build Coastguard Worker
379*8975f5c5SAndroid Build Coastguard Worker if (info->stencilBits > 0)
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker if (info->depthBits > 0)
382*8975f5c5SAndroid Build Coastguard Worker {
383*8975f5c5SAndroid Build Coastguard Worker // The internal format of the texture is DEPTH_STENCIL,
384*8975f5c5SAndroid Build Coastguard Worker // and the value of DEPTH_STENCIL_TEXTURE_MODE for the
385*8975f5c5SAndroid Build Coastguard Worker // texture is STENCIL_INDEX.
386*8975f5c5SAndroid Build Coastguard Worker if (mDepthStencilTextureMode == GL_STENCIL_INDEX)
387*8975f5c5SAndroid Build Coastguard Worker {
388*8975f5c5SAndroid Build Coastguard Worker return false;
389*8975f5c5SAndroid Build Coastguard Worker }
390*8975f5c5SAndroid Build Coastguard Worker }
391*8975f5c5SAndroid Build Coastguard Worker else
392*8975f5c5SAndroid Build Coastguard Worker {
393*8975f5c5SAndroid Build Coastguard Worker // The internal format is STENCIL_INDEX.
394*8975f5c5SAndroid Build Coastguard Worker return false;
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker }
397*8975f5c5SAndroid Build Coastguard Worker
398*8975f5c5SAndroid Build Coastguard Worker return true;
399*8975f5c5SAndroid Build Coastguard Worker }
400*8975f5c5SAndroid Build Coastguard Worker
401*8975f5c5SAndroid Build Coastguard Worker // CopyImageSubData has more lax rules for texture completeness: format-based completeness rules are
402*8975f5c5SAndroid Build Coastguard Worker // ignored, so a texture can still be considered complete even if it violates format-specific
403*8975f5c5SAndroid Build Coastguard Worker // conditions
computeSamplerCompletenessForCopyImage(const SamplerState & samplerState,const State & state) const404*8975f5c5SAndroid Build Coastguard Worker bool TextureState::computeSamplerCompletenessForCopyImage(const SamplerState &samplerState,
405*8975f5c5SAndroid Build Coastguard Worker const State &state) const
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker // Buffer textures cannot be incomplete. But if they are, the spec says -
408*8975f5c5SAndroid Build Coastguard Worker //
409*8975f5c5SAndroid Build Coastguard Worker // If no buffer object is bound to the buffer texture,
410*8975f5c5SAndroid Build Coastguard Worker // the results of the texel access are undefined.
411*8975f5c5SAndroid Build Coastguard Worker //
412*8975f5c5SAndroid Build Coastguard Worker // Mark as incomplete so we use the default IncompleteTexture instead
413*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::Buffer)
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker return mBuffer.get() != nullptr;
416*8975f5c5SAndroid Build Coastguard Worker }
417*8975f5c5SAndroid Build Coastguard Worker
418*8975f5c5SAndroid Build Coastguard Worker if (!mImmutableFormat && mBaseLevel > mMaxLevel)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker return false;
421*8975f5c5SAndroid Build Coastguard Worker }
422*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
423*8975f5c5SAndroid Build Coastguard Worker if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 ||
424*8975f5c5SAndroid Build Coastguard Worker baseImageDesc.size.depth == 0)
425*8975f5c5SAndroid Build Coastguard Worker {
426*8975f5c5SAndroid Build Coastguard Worker return false;
427*8975f5c5SAndroid Build Coastguard Worker }
428*8975f5c5SAndroid Build Coastguard Worker // The cases where the texture is incomplete because base level is out of range should be
429*8975f5c5SAndroid Build Coastguard Worker // handled by the above condition.
430*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBaseLevel < IMPLEMENTATION_MAX_TEXTURE_LEVELS || mImmutableFormat);
431*8975f5c5SAndroid Build Coastguard Worker
432*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::CubeMap && baseImageDesc.size.width != baseImageDesc.size.height)
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker return false;
435*8975f5c5SAndroid Build Coastguard Worker }
436*8975f5c5SAndroid Build Coastguard Worker
437*8975f5c5SAndroid Build Coastguard Worker bool npotSupport = state.getExtensions().textureNpotOES || state.getClientMajorVersion() >= 3;
438*8975f5c5SAndroid Build Coastguard Worker if (!npotSupport)
439*8975f5c5SAndroid Build Coastguard Worker {
440*8975f5c5SAndroid Build Coastguard Worker if ((samplerState.getWrapS() != GL_CLAMP_TO_EDGE &&
441*8975f5c5SAndroid Build Coastguard Worker samplerState.getWrapS() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.width)) ||
442*8975f5c5SAndroid Build Coastguard Worker (samplerState.getWrapT() != GL_CLAMP_TO_EDGE &&
443*8975f5c5SAndroid Build Coastguard Worker samplerState.getWrapT() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.height)))
444*8975f5c5SAndroid Build Coastguard Worker {
445*8975f5c5SAndroid Build Coastguard Worker return false;
446*8975f5c5SAndroid Build Coastguard Worker }
447*8975f5c5SAndroid Build Coastguard Worker }
448*8975f5c5SAndroid Build Coastguard Worker
449*8975f5c5SAndroid Build Coastguard Worker if (IsMipmapSupported(mType) && IsMipmapFiltered(samplerState.getMinFilter()))
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker if (!npotSupport)
452*8975f5c5SAndroid Build Coastguard Worker {
453*8975f5c5SAndroid Build Coastguard Worker if (!isPow2(baseImageDesc.size.width) || !isPow2(baseImageDesc.size.height))
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker return false;
456*8975f5c5SAndroid Build Coastguard Worker }
457*8975f5c5SAndroid Build Coastguard Worker }
458*8975f5c5SAndroid Build Coastguard Worker
459*8975f5c5SAndroid Build Coastguard Worker if (!computeMipmapCompleteness())
460*8975f5c5SAndroid Build Coastguard Worker {
461*8975f5c5SAndroid Build Coastguard Worker return false;
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker }
464*8975f5c5SAndroid Build Coastguard Worker else
465*8975f5c5SAndroid Build Coastguard Worker {
466*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::CubeMap && !isCubeComplete())
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker return false;
469*8975f5c5SAndroid Build Coastguard Worker }
470*8975f5c5SAndroid Build Coastguard Worker }
471*8975f5c5SAndroid Build Coastguard Worker
472*8975f5c5SAndroid Build Coastguard Worker // From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a
473*8975f5c5SAndroid Build Coastguard Worker // texture unit that would have been rejected by a call to TexParameter* for the texture bound
474*8975f5c5SAndroid Build Coastguard Worker // to that unit, the behavior of the implementation is as if the texture were incomplete. For
475*8975f5c5SAndroid Build Coastguard Worker // example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the
476*8975f5c5SAndroid Build Coastguard Worker // sampler object bound to a texture unit and the texture bound to that unit is an external
477*8975f5c5SAndroid Build Coastguard Worker // texture and EXT_EGL_image_external_wrap_modes is not enabled, the texture will be considered
478*8975f5c5SAndroid Build Coastguard Worker // incomplete.
479*8975f5c5SAndroid Build Coastguard Worker // Sampler object state which does not affect sampling for the type of texture bound
480*8975f5c5SAndroid Build Coastguard Worker // to a texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect
481*8975f5c5SAndroid Build Coastguard Worker // completeness.
482*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::External)
483*8975f5c5SAndroid Build Coastguard Worker {
484*8975f5c5SAndroid Build Coastguard Worker if (!state.getExtensions().EGLImageExternalWrapModesEXT)
485*8975f5c5SAndroid Build Coastguard Worker {
486*8975f5c5SAndroid Build Coastguard Worker if (samplerState.getWrapS() != GL_CLAMP_TO_EDGE ||
487*8975f5c5SAndroid Build Coastguard Worker samplerState.getWrapT() != GL_CLAMP_TO_EDGE)
488*8975f5c5SAndroid Build Coastguard Worker {
489*8975f5c5SAndroid Build Coastguard Worker return false;
490*8975f5c5SAndroid Build Coastguard Worker }
491*8975f5c5SAndroid Build Coastguard Worker }
492*8975f5c5SAndroid Build Coastguard Worker
493*8975f5c5SAndroid Build Coastguard Worker if (samplerState.getMinFilter() != GL_LINEAR && samplerState.getMinFilter() != GL_NEAREST)
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker return false;
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker }
498*8975f5c5SAndroid Build Coastguard Worker
499*8975f5c5SAndroid Build Coastguard Worker return true;
500*8975f5c5SAndroid Build Coastguard Worker }
501*8975f5c5SAndroid Build Coastguard Worker
computeMipmapCompleteness() const502*8975f5c5SAndroid Build Coastguard Worker bool TextureState::computeMipmapCompleteness() const
503*8975f5c5SAndroid Build Coastguard Worker {
504*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = getMipmapMaxLevel();
505*8975f5c5SAndroid Build Coastguard Worker
506*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = getEffectiveBaseLevel(); level <= maxLevel; level++)
507*8975f5c5SAndroid Build Coastguard Worker {
508*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::CubeMap)
509*8975f5c5SAndroid Build Coastguard Worker {
510*8975f5c5SAndroid Build Coastguard Worker for (TextureTarget face : AllCubeFaceTextureTargets())
511*8975f5c5SAndroid Build Coastguard Worker {
512*8975f5c5SAndroid Build Coastguard Worker if (!computeLevelCompleteness(face, level))
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker return false;
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker }
517*8975f5c5SAndroid Build Coastguard Worker }
518*8975f5c5SAndroid Build Coastguard Worker else
519*8975f5c5SAndroid Build Coastguard Worker {
520*8975f5c5SAndroid Build Coastguard Worker if (!computeLevelCompleteness(NonCubeTextureTypeToTarget(mType), level))
521*8975f5c5SAndroid Build Coastguard Worker {
522*8975f5c5SAndroid Build Coastguard Worker return false;
523*8975f5c5SAndroid Build Coastguard Worker }
524*8975f5c5SAndroid Build Coastguard Worker }
525*8975f5c5SAndroid Build Coastguard Worker }
526*8975f5c5SAndroid Build Coastguard Worker
527*8975f5c5SAndroid Build Coastguard Worker return true;
528*8975f5c5SAndroid Build Coastguard Worker }
529*8975f5c5SAndroid Build Coastguard Worker
computeLevelCompleteness(TextureTarget target,size_t level) const530*8975f5c5SAndroid Build Coastguard Worker bool TextureState::computeLevelCompleteness(TextureTarget target, size_t level) const
531*8975f5c5SAndroid Build Coastguard Worker {
532*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
533*8975f5c5SAndroid Build Coastguard Worker
534*8975f5c5SAndroid Build Coastguard Worker if (mImmutableFormat)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker return true;
537*8975f5c5SAndroid Build Coastguard Worker }
538*8975f5c5SAndroid Build Coastguard Worker
539*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
540*8975f5c5SAndroid Build Coastguard Worker if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 ||
541*8975f5c5SAndroid Build Coastguard Worker baseImageDesc.size.depth == 0)
542*8975f5c5SAndroid Build Coastguard Worker {
543*8975f5c5SAndroid Build Coastguard Worker return false;
544*8975f5c5SAndroid Build Coastguard Worker }
545*8975f5c5SAndroid Build Coastguard Worker
546*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &levelImageDesc = getImageDesc(target, level);
547*8975f5c5SAndroid Build Coastguard Worker if (levelImageDesc.size.width == 0 || levelImageDesc.size.height == 0 ||
548*8975f5c5SAndroid Build Coastguard Worker levelImageDesc.size.depth == 0)
549*8975f5c5SAndroid Build Coastguard Worker {
550*8975f5c5SAndroid Build Coastguard Worker return false;
551*8975f5c5SAndroid Build Coastguard Worker }
552*8975f5c5SAndroid Build Coastguard Worker
553*8975f5c5SAndroid Build Coastguard Worker if (!Format::SameSized(levelImageDesc.format, baseImageDesc.format))
554*8975f5c5SAndroid Build Coastguard Worker {
555*8975f5c5SAndroid Build Coastguard Worker return false;
556*8975f5c5SAndroid Build Coastguard Worker }
557*8975f5c5SAndroid Build Coastguard Worker
558*8975f5c5SAndroid Build Coastguard Worker ASSERT(level >= getEffectiveBaseLevel());
559*8975f5c5SAndroid Build Coastguard Worker const size_t relativeLevel = level - getEffectiveBaseLevel();
560*8975f5c5SAndroid Build Coastguard Worker if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel))
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker return false;
563*8975f5c5SAndroid Build Coastguard Worker }
564*8975f5c5SAndroid Build Coastguard Worker
565*8975f5c5SAndroid Build Coastguard Worker if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel))
566*8975f5c5SAndroid Build Coastguard Worker {
567*8975f5c5SAndroid Build Coastguard Worker return false;
568*8975f5c5SAndroid Build Coastguard Worker }
569*8975f5c5SAndroid Build Coastguard Worker
570*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::_3D)
571*8975f5c5SAndroid Build Coastguard Worker {
572*8975f5c5SAndroid Build Coastguard Worker if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
573*8975f5c5SAndroid Build Coastguard Worker {
574*8975f5c5SAndroid Build Coastguard Worker return false;
575*8975f5c5SAndroid Build Coastguard Worker }
576*8975f5c5SAndroid Build Coastguard Worker }
577*8975f5c5SAndroid Build Coastguard Worker else if (IsArrayTextureType(mType))
578*8975f5c5SAndroid Build Coastguard Worker {
579*8975f5c5SAndroid Build Coastguard Worker if (levelImageDesc.size.depth != baseImageDesc.size.depth)
580*8975f5c5SAndroid Build Coastguard Worker {
581*8975f5c5SAndroid Build Coastguard Worker return false;
582*8975f5c5SAndroid Build Coastguard Worker }
583*8975f5c5SAndroid Build Coastguard Worker }
584*8975f5c5SAndroid Build Coastguard Worker
585*8975f5c5SAndroid Build Coastguard Worker return true;
586*8975f5c5SAndroid Build Coastguard Worker }
587*8975f5c5SAndroid Build Coastguard Worker
getBaseImageTarget() const588*8975f5c5SAndroid Build Coastguard Worker TextureTarget TextureState::getBaseImageTarget() const
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker return mType == TextureType::CubeMap ? kCubeMapTextureTargetMin
591*8975f5c5SAndroid Build Coastguard Worker : NonCubeTextureTypeToTarget(mType);
592*8975f5c5SAndroid Build Coastguard Worker }
593*8975f5c5SAndroid Build Coastguard Worker
getEnabledLevelCount() const594*8975f5c5SAndroid Build Coastguard Worker GLuint TextureState::getEnabledLevelCount() const
595*8975f5c5SAndroid Build Coastguard Worker {
596*8975f5c5SAndroid Build Coastguard Worker GLuint levelCount = 0;
597*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = getEffectiveBaseLevel();
598*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = getMipmapMaxLevel();
599*8975f5c5SAndroid Build Coastguard Worker
600*8975f5c5SAndroid Build Coastguard Worker // The mip chain will have either one or more sequential levels, or max levels,
601*8975f5c5SAndroid Build Coastguard Worker // but not a sparse one.
602*8975f5c5SAndroid Build Coastguard Worker Optional<Extents> expectedSize;
603*8975f5c5SAndroid Build Coastguard Worker for (size_t enabledLevel = baseLevel; enabledLevel <= maxLevel; ++enabledLevel, ++levelCount)
604*8975f5c5SAndroid Build Coastguard Worker {
605*8975f5c5SAndroid Build Coastguard Worker // Note: for cube textures, we only check the first face.
606*8975f5c5SAndroid Build Coastguard Worker TextureTarget target = TextureTypeToTarget(mType, 0);
607*8975f5c5SAndroid Build Coastguard Worker size_t descIndex = GetImageDescIndex(target, enabledLevel);
608*8975f5c5SAndroid Build Coastguard Worker const Extents &levelSize = mImageDescs[descIndex].size;
609*8975f5c5SAndroid Build Coastguard Worker
610*8975f5c5SAndroid Build Coastguard Worker if (levelSize.empty())
611*8975f5c5SAndroid Build Coastguard Worker {
612*8975f5c5SAndroid Build Coastguard Worker break;
613*8975f5c5SAndroid Build Coastguard Worker }
614*8975f5c5SAndroid Build Coastguard Worker if (expectedSize.valid())
615*8975f5c5SAndroid Build Coastguard Worker {
616*8975f5c5SAndroid Build Coastguard Worker Extents newSize = expectedSize.value();
617*8975f5c5SAndroid Build Coastguard Worker newSize.width = std::max(1, newSize.width >> 1);
618*8975f5c5SAndroid Build Coastguard Worker newSize.height = std::max(1, newSize.height >> 1);
619*8975f5c5SAndroid Build Coastguard Worker
620*8975f5c5SAndroid Build Coastguard Worker if (!IsArrayTextureType(mType))
621*8975f5c5SAndroid Build Coastguard Worker {
622*8975f5c5SAndroid Build Coastguard Worker newSize.depth = std::max(1, newSize.depth >> 1);
623*8975f5c5SAndroid Build Coastguard Worker }
624*8975f5c5SAndroid Build Coastguard Worker
625*8975f5c5SAndroid Build Coastguard Worker if (newSize != levelSize)
626*8975f5c5SAndroid Build Coastguard Worker {
627*8975f5c5SAndroid Build Coastguard Worker break;
628*8975f5c5SAndroid Build Coastguard Worker }
629*8975f5c5SAndroid Build Coastguard Worker }
630*8975f5c5SAndroid Build Coastguard Worker expectedSize = levelSize;
631*8975f5c5SAndroid Build Coastguard Worker }
632*8975f5c5SAndroid Build Coastguard Worker
633*8975f5c5SAndroid Build Coastguard Worker return levelCount;
634*8975f5c5SAndroid Build Coastguard Worker }
635*8975f5c5SAndroid Build Coastguard Worker
ImageDesc()636*8975f5c5SAndroid Build Coastguard Worker ImageDesc::ImageDesc()
637*8975f5c5SAndroid Build Coastguard Worker : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized)
638*8975f5c5SAndroid Build Coastguard Worker {}
639*8975f5c5SAndroid Build Coastguard Worker
ImageDesc(const Extents & size,const Format & format,const InitState initState)640*8975f5c5SAndroid Build Coastguard Worker ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState)
641*8975f5c5SAndroid Build Coastguard Worker : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE), initState(initState)
642*8975f5c5SAndroid Build Coastguard Worker {}
643*8975f5c5SAndroid Build Coastguard Worker
ImageDesc(const Extents & size,const Format & format,const GLsizei samples,const bool fixedSampleLocations,const InitState initState)644*8975f5c5SAndroid Build Coastguard Worker ImageDesc::ImageDesc(const Extents &size,
645*8975f5c5SAndroid Build Coastguard Worker const Format &format,
646*8975f5c5SAndroid Build Coastguard Worker const GLsizei samples,
647*8975f5c5SAndroid Build Coastguard Worker const bool fixedSampleLocations,
648*8975f5c5SAndroid Build Coastguard Worker const InitState initState)
649*8975f5c5SAndroid Build Coastguard Worker : size(size),
650*8975f5c5SAndroid Build Coastguard Worker format(format),
651*8975f5c5SAndroid Build Coastguard Worker samples(samples),
652*8975f5c5SAndroid Build Coastguard Worker fixedSampleLocations(fixedSampleLocations),
653*8975f5c5SAndroid Build Coastguard Worker initState(initState)
654*8975f5c5SAndroid Build Coastguard Worker {}
655*8975f5c5SAndroid Build Coastguard Worker
getMemorySize() const656*8975f5c5SAndroid Build Coastguard Worker GLint ImageDesc::getMemorySize() const
657*8975f5c5SAndroid Build Coastguard Worker {
658*8975f5c5SAndroid Build Coastguard Worker // Assume allocated size is around width * height * depth * samples * pixelBytes
659*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<GLint> levelSize = 1;
660*8975f5c5SAndroid Build Coastguard Worker levelSize *= format.info->pixelBytes;
661*8975f5c5SAndroid Build Coastguard Worker levelSize *= size.width;
662*8975f5c5SAndroid Build Coastguard Worker levelSize *= size.height;
663*8975f5c5SAndroid Build Coastguard Worker levelSize *= size.depth;
664*8975f5c5SAndroid Build Coastguard Worker levelSize *= std::max(samples, 1);
665*8975f5c5SAndroid Build Coastguard Worker return levelSize.ValueOrDefault(std::numeric_limits<GLint>::max());
666*8975f5c5SAndroid Build Coastguard Worker }
667*8975f5c5SAndroid Build Coastguard Worker
getImageDesc(TextureTarget target,size_t level) const668*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const
669*8975f5c5SAndroid Build Coastguard Worker {
670*8975f5c5SAndroid Build Coastguard Worker size_t descIndex = GetImageDescIndex(target, level);
671*8975f5c5SAndroid Build Coastguard Worker ASSERT(descIndex < mImageDescs.size());
672*8975f5c5SAndroid Build Coastguard Worker return mImageDescs[descIndex];
673*8975f5c5SAndroid Build Coastguard Worker }
674*8975f5c5SAndroid Build Coastguard Worker
setImageDesc(TextureTarget target,size_t level,const ImageDesc & desc)675*8975f5c5SAndroid Build Coastguard Worker void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc)
676*8975f5c5SAndroid Build Coastguard Worker {
677*8975f5c5SAndroid Build Coastguard Worker size_t descIndex = GetImageDescIndex(target, level);
678*8975f5c5SAndroid Build Coastguard Worker ASSERT(descIndex < mImageDescs.size());
679*8975f5c5SAndroid Build Coastguard Worker mImageDescs[descIndex] = desc;
680*8975f5c5SAndroid Build Coastguard Worker if (desc.initState == InitState::MayNeedInit)
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker mInitState = InitState::MayNeedInit;
683*8975f5c5SAndroid Build Coastguard Worker }
684*8975f5c5SAndroid Build Coastguard Worker else
685*8975f5c5SAndroid Build Coastguard Worker {
686*8975f5c5SAndroid Build Coastguard Worker // Scan for any uninitialized images. If there are none, set the init state of the entire
687*8975f5c5SAndroid Build Coastguard Worker // texture to initialized. The cost of the scan is only paid after doing image
688*8975f5c5SAndroid Build Coastguard Worker // initialization which is already very expensive.
689*8975f5c5SAndroid Build Coastguard Worker bool allImagesInitialized = true;
690*8975f5c5SAndroid Build Coastguard Worker
691*8975f5c5SAndroid Build Coastguard Worker for (const ImageDesc &initDesc : mImageDescs)
692*8975f5c5SAndroid Build Coastguard Worker {
693*8975f5c5SAndroid Build Coastguard Worker if (initDesc.initState == InitState::MayNeedInit)
694*8975f5c5SAndroid Build Coastguard Worker {
695*8975f5c5SAndroid Build Coastguard Worker allImagesInitialized = false;
696*8975f5c5SAndroid Build Coastguard Worker break;
697*8975f5c5SAndroid Build Coastguard Worker }
698*8975f5c5SAndroid Build Coastguard Worker }
699*8975f5c5SAndroid Build Coastguard Worker
700*8975f5c5SAndroid Build Coastguard Worker if (allImagesInitialized)
701*8975f5c5SAndroid Build Coastguard Worker {
702*8975f5c5SAndroid Build Coastguard Worker mInitState = InitState::Initialized;
703*8975f5c5SAndroid Build Coastguard Worker }
704*8975f5c5SAndroid Build Coastguard Worker }
705*8975f5c5SAndroid Build Coastguard Worker }
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Worker // Note that an ImageIndex that represents an entire level of a cube map corresponds to 6
708*8975f5c5SAndroid Build Coastguard Worker // ImageDescs, so if the cube map is cube complete, we return the ImageDesc of the first cube
709*8975f5c5SAndroid Build Coastguard Worker // face, and we don't allow using this function when the cube map is not cube complete.
getImageDesc(const ImageIndex & imageIndex) const710*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const
711*8975f5c5SAndroid Build Coastguard Worker {
712*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
713*8975f5c5SAndroid Build Coastguard Worker {
714*8975f5c5SAndroid Build Coastguard Worker ASSERT(isCubeComplete());
715*8975f5c5SAndroid Build Coastguard Worker const GLint levelIndex = imageIndex.getLevelIndex();
716*8975f5c5SAndroid Build Coastguard Worker return getImageDesc(kCubeMapTextureTargetMin, levelIndex);
717*8975f5c5SAndroid Build Coastguard Worker }
718*8975f5c5SAndroid Build Coastguard Worker
719*8975f5c5SAndroid Build Coastguard Worker return getImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex());
720*8975f5c5SAndroid Build Coastguard Worker }
721*8975f5c5SAndroid Build Coastguard Worker
setImageDescChain(GLuint baseLevel,GLuint maxLevel,Extents baseSize,const Format & format,InitState initState)722*8975f5c5SAndroid Build Coastguard Worker void TextureState::setImageDescChain(GLuint baseLevel,
723*8975f5c5SAndroid Build Coastguard Worker GLuint maxLevel,
724*8975f5c5SAndroid Build Coastguard Worker Extents baseSize,
725*8975f5c5SAndroid Build Coastguard Worker const Format &format,
726*8975f5c5SAndroid Build Coastguard Worker InitState initState)
727*8975f5c5SAndroid Build Coastguard Worker {
728*8975f5c5SAndroid Build Coastguard Worker for (GLuint level = baseLevel; level <= maxLevel; level++)
729*8975f5c5SAndroid Build Coastguard Worker {
730*8975f5c5SAndroid Build Coastguard Worker int relativeLevel = (level - baseLevel);
731*8975f5c5SAndroid Build Coastguard Worker Extents levelSize(std::max<int>(baseSize.width >> relativeLevel, 1),
732*8975f5c5SAndroid Build Coastguard Worker std::max<int>(baseSize.height >> relativeLevel, 1),
733*8975f5c5SAndroid Build Coastguard Worker (IsArrayTextureType(mType))
734*8975f5c5SAndroid Build Coastguard Worker ? baseSize.depth
735*8975f5c5SAndroid Build Coastguard Worker : std::max<int>(baseSize.depth >> relativeLevel, 1));
736*8975f5c5SAndroid Build Coastguard Worker ImageDesc levelInfo(levelSize, format, initState);
737*8975f5c5SAndroid Build Coastguard Worker
738*8975f5c5SAndroid Build Coastguard Worker if (mType == TextureType::CubeMap)
739*8975f5c5SAndroid Build Coastguard Worker {
740*8975f5c5SAndroid Build Coastguard Worker for (TextureTarget face : AllCubeFaceTextureTargets())
741*8975f5c5SAndroid Build Coastguard Worker {
742*8975f5c5SAndroid Build Coastguard Worker setImageDesc(face, level, levelInfo);
743*8975f5c5SAndroid Build Coastguard Worker }
744*8975f5c5SAndroid Build Coastguard Worker }
745*8975f5c5SAndroid Build Coastguard Worker else
746*8975f5c5SAndroid Build Coastguard Worker {
747*8975f5c5SAndroid Build Coastguard Worker setImageDesc(NonCubeTextureTypeToTarget(mType), level, levelInfo);
748*8975f5c5SAndroid Build Coastguard Worker }
749*8975f5c5SAndroid Build Coastguard Worker }
750*8975f5c5SAndroid Build Coastguard Worker }
751*8975f5c5SAndroid Build Coastguard Worker
setImageDescChainMultisample(Extents baseSize,const Format & format,GLsizei samples,bool fixedSampleLocations,InitState initState)752*8975f5c5SAndroid Build Coastguard Worker void TextureState::setImageDescChainMultisample(Extents baseSize,
753*8975f5c5SAndroid Build Coastguard Worker const Format &format,
754*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
755*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations,
756*8975f5c5SAndroid Build Coastguard Worker InitState initState)
757*8975f5c5SAndroid Build Coastguard Worker {
758*8975f5c5SAndroid Build Coastguard Worker ASSERT(mType == TextureType::_2DMultisample || mType == TextureType::_2DMultisampleArray);
759*8975f5c5SAndroid Build Coastguard Worker ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState);
760*8975f5c5SAndroid Build Coastguard Worker setImageDesc(NonCubeTextureTypeToTarget(mType), 0, levelInfo);
761*8975f5c5SAndroid Build Coastguard Worker }
762*8975f5c5SAndroid Build Coastguard Worker
clearImageDesc(TextureTarget target,size_t level)763*8975f5c5SAndroid Build Coastguard Worker void TextureState::clearImageDesc(TextureTarget target, size_t level)
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker setImageDesc(target, level, ImageDesc());
766*8975f5c5SAndroid Build Coastguard Worker }
767*8975f5c5SAndroid Build Coastguard Worker
clearImageDescs()768*8975f5c5SAndroid Build Coastguard Worker void TextureState::clearImageDescs()
769*8975f5c5SAndroid Build Coastguard Worker {
770*8975f5c5SAndroid Build Coastguard Worker for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++)
771*8975f5c5SAndroid Build Coastguard Worker {
772*8975f5c5SAndroid Build Coastguard Worker mImageDescs[descIndex] = ImageDesc();
773*8975f5c5SAndroid Build Coastguard Worker }
774*8975f5c5SAndroid Build Coastguard Worker }
775*8975f5c5SAndroid Build Coastguard Worker
TextureBufferContentsObservers(Texture * texture)776*8975f5c5SAndroid Build Coastguard Worker TextureBufferContentsObservers::TextureBufferContentsObservers(Texture *texture) : mTexture(texture)
777*8975f5c5SAndroid Build Coastguard Worker {}
778*8975f5c5SAndroid Build Coastguard Worker
enableForBuffer(Buffer * buffer)779*8975f5c5SAndroid Build Coastguard Worker void TextureBufferContentsObservers::enableForBuffer(Buffer *buffer)
780*8975f5c5SAndroid Build Coastguard Worker {
781*8975f5c5SAndroid Build Coastguard Worker buffer->addContentsObserver(mTexture);
782*8975f5c5SAndroid Build Coastguard Worker }
783*8975f5c5SAndroid Build Coastguard Worker
disableForBuffer(Buffer * buffer)784*8975f5c5SAndroid Build Coastguard Worker void TextureBufferContentsObservers::disableForBuffer(Buffer *buffer)
785*8975f5c5SAndroid Build Coastguard Worker {
786*8975f5c5SAndroid Build Coastguard Worker buffer->removeContentsObserver(mTexture);
787*8975f5c5SAndroid Build Coastguard Worker }
788*8975f5c5SAndroid Build Coastguard Worker
Texture(rx::GLImplFactory * factory,TextureID id,TextureType type)789*8975f5c5SAndroid Build Coastguard Worker Texture::Texture(rx::GLImplFactory *factory, TextureID id, TextureType type)
790*8975f5c5SAndroid Build Coastguard Worker : RefCountObject(factory->generateSerial(), id),
791*8975f5c5SAndroid Build Coastguard Worker mState(type),
792*8975f5c5SAndroid Build Coastguard Worker mTexture(factory->createTexture(mState)),
793*8975f5c5SAndroid Build Coastguard Worker mImplObserver(this, rx::kTextureImageImplObserverMessageIndex),
794*8975f5c5SAndroid Build Coastguard Worker mBufferObserver(this, kBufferSubjectIndex),
795*8975f5c5SAndroid Build Coastguard Worker mBoundSurface(nullptr),
796*8975f5c5SAndroid Build Coastguard Worker mBoundStream(nullptr),
797*8975f5c5SAndroid Build Coastguard Worker mBufferContentsObservers(this)
798*8975f5c5SAndroid Build Coastguard Worker {
799*8975f5c5SAndroid Build Coastguard Worker mImplObserver.bind(mTexture);
800*8975f5c5SAndroid Build Coastguard Worker if (mTexture)
801*8975f5c5SAndroid Build Coastguard Worker {
802*8975f5c5SAndroid Build Coastguard Worker mTexture->setContentsObservers(&mBufferContentsObservers);
803*8975f5c5SAndroid Build Coastguard Worker }
804*8975f5c5SAndroid Build Coastguard Worker
805*8975f5c5SAndroid Build Coastguard Worker // Initially assume the implementation is dirty.
806*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_IMPLEMENTATION);
807*8975f5c5SAndroid Build Coastguard Worker }
808*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const Context * context)809*8975f5c5SAndroid Build Coastguard Worker void Texture::onDestroy(const Context *context)
810*8975f5c5SAndroid Build Coastguard Worker {
811*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::TextureIDDeleted);
812*8975f5c5SAndroid Build Coastguard Worker
813*8975f5c5SAndroid Build Coastguard Worker if (mBoundSurface)
814*8975f5c5SAndroid Build Coastguard Worker {
815*8975f5c5SAndroid Build Coastguard Worker ANGLE_SWALLOW_ERR(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER));
816*8975f5c5SAndroid Build Coastguard Worker mBoundSurface = nullptr;
817*8975f5c5SAndroid Build Coastguard Worker }
818*8975f5c5SAndroid Build Coastguard Worker if (mBoundStream)
819*8975f5c5SAndroid Build Coastguard Worker {
820*8975f5c5SAndroid Build Coastguard Worker mBoundStream->releaseTextures();
821*8975f5c5SAndroid Build Coastguard Worker mBoundStream = nullptr;
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker
824*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
825*8975f5c5SAndroid Build Coastguard Worker (void)orphanImages(context, &releaseImage);
826*8975f5c5SAndroid Build Coastguard Worker
827*8975f5c5SAndroid Build Coastguard Worker mState.mBuffer.set(context, nullptr, 0, 0);
828*8975f5c5SAndroid Build Coastguard Worker
829*8975f5c5SAndroid Build Coastguard Worker if (mTexture)
830*8975f5c5SAndroid Build Coastguard Worker {
831*8975f5c5SAndroid Build Coastguard Worker mTexture->onDestroy(context);
832*8975f5c5SAndroid Build Coastguard Worker }
833*8975f5c5SAndroid Build Coastguard Worker }
834*8975f5c5SAndroid Build Coastguard Worker
~Texture()835*8975f5c5SAndroid Build Coastguard Worker Texture::~Texture()
836*8975f5c5SAndroid Build Coastguard Worker {
837*8975f5c5SAndroid Build Coastguard Worker SafeDelete(mTexture);
838*8975f5c5SAndroid Build Coastguard Worker }
839*8975f5c5SAndroid Build Coastguard Worker
setLabel(const Context * context,const std::string & label)840*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setLabel(const Context *context, const std::string &label)
841*8975f5c5SAndroid Build Coastguard Worker {
842*8975f5c5SAndroid Build Coastguard Worker mState.mLabel = label;
843*8975f5c5SAndroid Build Coastguard Worker return mTexture->onLabelUpdate(context);
844*8975f5c5SAndroid Build Coastguard Worker }
845*8975f5c5SAndroid Build Coastguard Worker
getLabel() const846*8975f5c5SAndroid Build Coastguard Worker const std::string &Texture::getLabel() const
847*8975f5c5SAndroid Build Coastguard Worker {
848*8975f5c5SAndroid Build Coastguard Worker return mState.mLabel;
849*8975f5c5SAndroid Build Coastguard Worker }
850*8975f5c5SAndroid Build Coastguard Worker
setSwizzleRed(const Context * context,GLenum swizzleRed)851*8975f5c5SAndroid Build Coastguard Worker void Texture::setSwizzleRed(const Context *context, GLenum swizzleRed)
852*8975f5c5SAndroid Build Coastguard Worker {
853*8975f5c5SAndroid Build Coastguard Worker if (mState.mSwizzleState.swizzleRed != swizzleRed)
854*8975f5c5SAndroid Build Coastguard Worker {
855*8975f5c5SAndroid Build Coastguard Worker mState.mSwizzleState.swizzleRed = swizzleRed;
856*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SWIZZLE_RED);
857*8975f5c5SAndroid Build Coastguard Worker }
858*8975f5c5SAndroid Build Coastguard Worker }
859*8975f5c5SAndroid Build Coastguard Worker
getSwizzleRed() const860*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSwizzleRed() const
861*8975f5c5SAndroid Build Coastguard Worker {
862*8975f5c5SAndroid Build Coastguard Worker return mState.mSwizzleState.swizzleRed;
863*8975f5c5SAndroid Build Coastguard Worker }
864*8975f5c5SAndroid Build Coastguard Worker
setSwizzleGreen(const Context * context,GLenum swizzleGreen)865*8975f5c5SAndroid Build Coastguard Worker void Texture::setSwizzleGreen(const Context *context, GLenum swizzleGreen)
866*8975f5c5SAndroid Build Coastguard Worker {
867*8975f5c5SAndroid Build Coastguard Worker if (mState.mSwizzleState.swizzleGreen != swizzleGreen)
868*8975f5c5SAndroid Build Coastguard Worker {
869*8975f5c5SAndroid Build Coastguard Worker mState.mSwizzleState.swizzleGreen = swizzleGreen;
870*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SWIZZLE_GREEN);
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker }
873*8975f5c5SAndroid Build Coastguard Worker
getSwizzleGreen() const874*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSwizzleGreen() const
875*8975f5c5SAndroid Build Coastguard Worker {
876*8975f5c5SAndroid Build Coastguard Worker return mState.mSwizzleState.swizzleGreen;
877*8975f5c5SAndroid Build Coastguard Worker }
878*8975f5c5SAndroid Build Coastguard Worker
setSwizzleBlue(const Context * context,GLenum swizzleBlue)879*8975f5c5SAndroid Build Coastguard Worker void Texture::setSwizzleBlue(const Context *context, GLenum swizzleBlue)
880*8975f5c5SAndroid Build Coastguard Worker {
881*8975f5c5SAndroid Build Coastguard Worker if (mState.mSwizzleState.swizzleBlue != swizzleBlue)
882*8975f5c5SAndroid Build Coastguard Worker {
883*8975f5c5SAndroid Build Coastguard Worker mState.mSwizzleState.swizzleBlue = swizzleBlue;
884*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SWIZZLE_BLUE);
885*8975f5c5SAndroid Build Coastguard Worker }
886*8975f5c5SAndroid Build Coastguard Worker }
887*8975f5c5SAndroid Build Coastguard Worker
getSwizzleBlue() const888*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSwizzleBlue() const
889*8975f5c5SAndroid Build Coastguard Worker {
890*8975f5c5SAndroid Build Coastguard Worker return mState.mSwizzleState.swizzleBlue;
891*8975f5c5SAndroid Build Coastguard Worker }
892*8975f5c5SAndroid Build Coastguard Worker
setSwizzleAlpha(const Context * context,GLenum swizzleAlpha)893*8975f5c5SAndroid Build Coastguard Worker void Texture::setSwizzleAlpha(const Context *context, GLenum swizzleAlpha)
894*8975f5c5SAndroid Build Coastguard Worker {
895*8975f5c5SAndroid Build Coastguard Worker if (mState.mSwizzleState.swizzleAlpha != swizzleAlpha)
896*8975f5c5SAndroid Build Coastguard Worker {
897*8975f5c5SAndroid Build Coastguard Worker mState.mSwizzleState.swizzleAlpha = swizzleAlpha;
898*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SWIZZLE_ALPHA);
899*8975f5c5SAndroid Build Coastguard Worker }
900*8975f5c5SAndroid Build Coastguard Worker }
901*8975f5c5SAndroid Build Coastguard Worker
getSwizzleAlpha() const902*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSwizzleAlpha() const
903*8975f5c5SAndroid Build Coastguard Worker {
904*8975f5c5SAndroid Build Coastguard Worker return mState.mSwizzleState.swizzleAlpha;
905*8975f5c5SAndroid Build Coastguard Worker }
906*8975f5c5SAndroid Build Coastguard Worker
setMinFilter(const Context * context,GLenum minFilter)907*8975f5c5SAndroid Build Coastguard Worker void Texture::setMinFilter(const Context *context, GLenum minFilter)
908*8975f5c5SAndroid Build Coastguard Worker {
909*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setMinFilter(minFilter))
910*8975f5c5SAndroid Build Coastguard Worker {
911*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MIN_FILTER);
912*8975f5c5SAndroid Build Coastguard Worker }
913*8975f5c5SAndroid Build Coastguard Worker }
914*8975f5c5SAndroid Build Coastguard Worker
getMinFilter() const915*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getMinFilter() const
916*8975f5c5SAndroid Build Coastguard Worker {
917*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getMinFilter();
918*8975f5c5SAndroid Build Coastguard Worker }
919*8975f5c5SAndroid Build Coastguard Worker
setMagFilter(const Context * context,GLenum magFilter)920*8975f5c5SAndroid Build Coastguard Worker void Texture::setMagFilter(const Context *context, GLenum magFilter)
921*8975f5c5SAndroid Build Coastguard Worker {
922*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setMagFilter(magFilter))
923*8975f5c5SAndroid Build Coastguard Worker {
924*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MAG_FILTER);
925*8975f5c5SAndroid Build Coastguard Worker }
926*8975f5c5SAndroid Build Coastguard Worker }
927*8975f5c5SAndroid Build Coastguard Worker
getMagFilter() const928*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getMagFilter() const
929*8975f5c5SAndroid Build Coastguard Worker {
930*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getMagFilter();
931*8975f5c5SAndroid Build Coastguard Worker }
932*8975f5c5SAndroid Build Coastguard Worker
setWrapS(const Context * context,GLenum wrapS)933*8975f5c5SAndroid Build Coastguard Worker void Texture::setWrapS(const Context *context, GLenum wrapS)
934*8975f5c5SAndroid Build Coastguard Worker {
935*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setWrapS(wrapS))
936*8975f5c5SAndroid Build Coastguard Worker {
937*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_WRAP_S);
938*8975f5c5SAndroid Build Coastguard Worker }
939*8975f5c5SAndroid Build Coastguard Worker }
940*8975f5c5SAndroid Build Coastguard Worker
getWrapS() const941*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getWrapS() const
942*8975f5c5SAndroid Build Coastguard Worker {
943*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getWrapS();
944*8975f5c5SAndroid Build Coastguard Worker }
945*8975f5c5SAndroid Build Coastguard Worker
setWrapT(const Context * context,GLenum wrapT)946*8975f5c5SAndroid Build Coastguard Worker void Texture::setWrapT(const Context *context, GLenum wrapT)
947*8975f5c5SAndroid Build Coastguard Worker {
948*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.getWrapT() == wrapT)
949*8975f5c5SAndroid Build Coastguard Worker return;
950*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setWrapT(wrapT))
951*8975f5c5SAndroid Build Coastguard Worker {
952*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_WRAP_T);
953*8975f5c5SAndroid Build Coastguard Worker }
954*8975f5c5SAndroid Build Coastguard Worker }
955*8975f5c5SAndroid Build Coastguard Worker
getWrapT() const956*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getWrapT() const
957*8975f5c5SAndroid Build Coastguard Worker {
958*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getWrapT();
959*8975f5c5SAndroid Build Coastguard Worker }
960*8975f5c5SAndroid Build Coastguard Worker
setWrapR(const Context * context,GLenum wrapR)961*8975f5c5SAndroid Build Coastguard Worker void Texture::setWrapR(const Context *context, GLenum wrapR)
962*8975f5c5SAndroid Build Coastguard Worker {
963*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setWrapR(wrapR))
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_WRAP_R);
966*8975f5c5SAndroid Build Coastguard Worker }
967*8975f5c5SAndroid Build Coastguard Worker }
968*8975f5c5SAndroid Build Coastguard Worker
getWrapR() const969*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getWrapR() const
970*8975f5c5SAndroid Build Coastguard Worker {
971*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getWrapR();
972*8975f5c5SAndroid Build Coastguard Worker }
973*8975f5c5SAndroid Build Coastguard Worker
setMaxAnisotropy(const Context * context,float maxAnisotropy)974*8975f5c5SAndroid Build Coastguard Worker void Texture::setMaxAnisotropy(const Context *context, float maxAnisotropy)
975*8975f5c5SAndroid Build Coastguard Worker {
976*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setMaxAnisotropy(maxAnisotropy))
977*8975f5c5SAndroid Build Coastguard Worker {
978*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MAX_ANISOTROPY);
979*8975f5c5SAndroid Build Coastguard Worker }
980*8975f5c5SAndroid Build Coastguard Worker }
981*8975f5c5SAndroid Build Coastguard Worker
getMaxAnisotropy() const982*8975f5c5SAndroid Build Coastguard Worker float Texture::getMaxAnisotropy() const
983*8975f5c5SAndroid Build Coastguard Worker {
984*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getMaxAnisotropy();
985*8975f5c5SAndroid Build Coastguard Worker }
986*8975f5c5SAndroid Build Coastguard Worker
setMinLod(const Context * context,GLfloat minLod)987*8975f5c5SAndroid Build Coastguard Worker void Texture::setMinLod(const Context *context, GLfloat minLod)
988*8975f5c5SAndroid Build Coastguard Worker {
989*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setMinLod(minLod))
990*8975f5c5SAndroid Build Coastguard Worker {
991*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MIN_LOD);
992*8975f5c5SAndroid Build Coastguard Worker }
993*8975f5c5SAndroid Build Coastguard Worker }
994*8975f5c5SAndroid Build Coastguard Worker
getMinLod() const995*8975f5c5SAndroid Build Coastguard Worker GLfloat Texture::getMinLod() const
996*8975f5c5SAndroid Build Coastguard Worker {
997*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getMinLod();
998*8975f5c5SAndroid Build Coastguard Worker }
999*8975f5c5SAndroid Build Coastguard Worker
setMaxLod(const Context * context,GLfloat maxLod)1000*8975f5c5SAndroid Build Coastguard Worker void Texture::setMaxLod(const Context *context, GLfloat maxLod)
1001*8975f5c5SAndroid Build Coastguard Worker {
1002*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setMaxLod(maxLod))
1003*8975f5c5SAndroid Build Coastguard Worker {
1004*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MAX_LOD);
1005*8975f5c5SAndroid Build Coastguard Worker }
1006*8975f5c5SAndroid Build Coastguard Worker }
1007*8975f5c5SAndroid Build Coastguard Worker
getMaxLod() const1008*8975f5c5SAndroid Build Coastguard Worker GLfloat Texture::getMaxLod() const
1009*8975f5c5SAndroid Build Coastguard Worker {
1010*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getMaxLod();
1011*8975f5c5SAndroid Build Coastguard Worker }
1012*8975f5c5SAndroid Build Coastguard Worker
setCompareMode(const Context * context,GLenum compareMode)1013*8975f5c5SAndroid Build Coastguard Worker void Texture::setCompareMode(const Context *context, GLenum compareMode)
1014*8975f5c5SAndroid Build Coastguard Worker {
1015*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setCompareMode(compareMode))
1016*8975f5c5SAndroid Build Coastguard Worker {
1017*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_COMPARE_MODE);
1018*8975f5c5SAndroid Build Coastguard Worker }
1019*8975f5c5SAndroid Build Coastguard Worker }
1020*8975f5c5SAndroid Build Coastguard Worker
getCompareMode() const1021*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getCompareMode() const
1022*8975f5c5SAndroid Build Coastguard Worker {
1023*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getCompareMode();
1024*8975f5c5SAndroid Build Coastguard Worker }
1025*8975f5c5SAndroid Build Coastguard Worker
setCompareFunc(const Context * context,GLenum compareFunc)1026*8975f5c5SAndroid Build Coastguard Worker void Texture::setCompareFunc(const Context *context, GLenum compareFunc)
1027*8975f5c5SAndroid Build Coastguard Worker {
1028*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setCompareFunc(compareFunc))
1029*8975f5c5SAndroid Build Coastguard Worker {
1030*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_COMPARE_FUNC);
1031*8975f5c5SAndroid Build Coastguard Worker }
1032*8975f5c5SAndroid Build Coastguard Worker }
1033*8975f5c5SAndroid Build Coastguard Worker
getCompareFunc() const1034*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getCompareFunc() const
1035*8975f5c5SAndroid Build Coastguard Worker {
1036*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getCompareFunc();
1037*8975f5c5SAndroid Build Coastguard Worker }
1038*8975f5c5SAndroid Build Coastguard Worker
setSRGBDecode(const Context * context,GLenum sRGBDecode)1039*8975f5c5SAndroid Build Coastguard Worker void Texture::setSRGBDecode(const Context *context, GLenum sRGBDecode)
1040*8975f5c5SAndroid Build Coastguard Worker {
1041*8975f5c5SAndroid Build Coastguard Worker if (mState.mSamplerState.setSRGBDecode(sRGBDecode))
1042*8975f5c5SAndroid Build Coastguard Worker {
1043*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SRGB_DECODE);
1044*8975f5c5SAndroid Build Coastguard Worker }
1045*8975f5c5SAndroid Build Coastguard Worker }
1046*8975f5c5SAndroid Build Coastguard Worker
getSRGBDecode() const1047*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSRGBDecode() const
1048*8975f5c5SAndroid Build Coastguard Worker {
1049*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getSRGBDecode();
1050*8975f5c5SAndroid Build Coastguard Worker }
1051*8975f5c5SAndroid Build Coastguard Worker
setSRGBOverride(const Context * context,GLenum sRGBOverride)1052*8975f5c5SAndroid Build Coastguard Worker void Texture::setSRGBOverride(const Context *context, GLenum sRGBOverride)
1053*8975f5c5SAndroid Build Coastguard Worker {
1054*8975f5c5SAndroid Build Coastguard Worker SrgbOverride oldOverride = mState.mSrgbOverride;
1055*8975f5c5SAndroid Build Coastguard Worker mState.mSrgbOverride = (sRGBOverride == GL_SRGB) ? SrgbOverride::SRGB : SrgbOverride::Default;
1056*8975f5c5SAndroid Build Coastguard Worker if (mState.mSrgbOverride != oldOverride)
1057*8975f5c5SAndroid Build Coastguard Worker {
1058*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_SRGB_OVERRIDE);
1059*8975f5c5SAndroid Build Coastguard Worker }
1060*8975f5c5SAndroid Build Coastguard Worker }
1061*8975f5c5SAndroid Build Coastguard Worker
getSRGBOverride() const1062*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getSRGBOverride() const
1063*8975f5c5SAndroid Build Coastguard Worker {
1064*8975f5c5SAndroid Build Coastguard Worker return (mState.mSrgbOverride == SrgbOverride::SRGB) ? GL_SRGB : GL_NONE;
1065*8975f5c5SAndroid Build Coastguard Worker }
1066*8975f5c5SAndroid Build Coastguard Worker
getSamplerState() const1067*8975f5c5SAndroid Build Coastguard Worker const SamplerState &Texture::getSamplerState() const
1068*8975f5c5SAndroid Build Coastguard Worker {
1069*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState;
1070*8975f5c5SAndroid Build Coastguard Worker }
1071*8975f5c5SAndroid Build Coastguard Worker
setBaseLevel(const Context * context,GLuint baseLevel)1072*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setBaseLevel(const Context *context, GLuint baseLevel)
1073*8975f5c5SAndroid Build Coastguard Worker {
1074*8975f5c5SAndroid Build Coastguard Worker if (mState.setBaseLevel(baseLevel))
1075*8975f5c5SAndroid Build Coastguard Worker {
1076*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel()));
1077*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_BASE_LEVEL);
1078*8975f5c5SAndroid Build Coastguard Worker }
1079*8975f5c5SAndroid Build Coastguard Worker
1080*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1081*8975f5c5SAndroid Build Coastguard Worker }
1082*8975f5c5SAndroid Build Coastguard Worker
getBaseLevel() const1083*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getBaseLevel() const
1084*8975f5c5SAndroid Build Coastguard Worker {
1085*8975f5c5SAndroid Build Coastguard Worker return mState.mBaseLevel;
1086*8975f5c5SAndroid Build Coastguard Worker }
1087*8975f5c5SAndroid Build Coastguard Worker
setMaxLevel(const Context * context,GLuint maxLevel)1088*8975f5c5SAndroid Build Coastguard Worker void Texture::setMaxLevel(const Context *context, GLuint maxLevel)
1089*8975f5c5SAndroid Build Coastguard Worker {
1090*8975f5c5SAndroid Build Coastguard Worker if (mState.setMaxLevel(maxLevel))
1091*8975f5c5SAndroid Build Coastguard Worker {
1092*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_MAX_LEVEL);
1093*8975f5c5SAndroid Build Coastguard Worker }
1094*8975f5c5SAndroid Build Coastguard Worker }
1095*8975f5c5SAndroid Build Coastguard Worker
getMaxLevel() const1096*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getMaxLevel() const
1097*8975f5c5SAndroid Build Coastguard Worker {
1098*8975f5c5SAndroid Build Coastguard Worker return mState.mMaxLevel;
1099*8975f5c5SAndroid Build Coastguard Worker }
1100*8975f5c5SAndroid Build Coastguard Worker
setDepthStencilTextureMode(const Context * context,GLenum mode)1101*8975f5c5SAndroid Build Coastguard Worker void Texture::setDepthStencilTextureMode(const Context *context, GLenum mode)
1102*8975f5c5SAndroid Build Coastguard Worker {
1103*8975f5c5SAndroid Build Coastguard Worker if (mState.mDepthStencilTextureMode != mode)
1104*8975f5c5SAndroid Build Coastguard Worker {
1105*8975f5c5SAndroid Build Coastguard Worker mState.mDepthStencilTextureMode = mode;
1106*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
1107*8975f5c5SAndroid Build Coastguard Worker }
1108*8975f5c5SAndroid Build Coastguard Worker }
1109*8975f5c5SAndroid Build Coastguard Worker
getDepthStencilTextureMode() const1110*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getDepthStencilTextureMode() const
1111*8975f5c5SAndroid Build Coastguard Worker {
1112*8975f5c5SAndroid Build Coastguard Worker return mState.mDepthStencilTextureMode;
1113*8975f5c5SAndroid Build Coastguard Worker }
1114*8975f5c5SAndroid Build Coastguard Worker
getImmutableFormat() const1115*8975f5c5SAndroid Build Coastguard Worker bool Texture::getImmutableFormat() const
1116*8975f5c5SAndroid Build Coastguard Worker {
1117*8975f5c5SAndroid Build Coastguard Worker return mState.mImmutableFormat;
1118*8975f5c5SAndroid Build Coastguard Worker }
1119*8975f5c5SAndroid Build Coastguard Worker
getImmutableLevels() const1120*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getImmutableLevels() const
1121*8975f5c5SAndroid Build Coastguard Worker {
1122*8975f5c5SAndroid Build Coastguard Worker return mState.mImmutableLevels;
1123*8975f5c5SAndroid Build Coastguard Worker }
1124*8975f5c5SAndroid Build Coastguard Worker
setUsage(const Context * context,GLenum usage)1125*8975f5c5SAndroid Build Coastguard Worker void Texture::setUsage(const Context *context, GLenum usage)
1126*8975f5c5SAndroid Build Coastguard Worker {
1127*8975f5c5SAndroid Build Coastguard Worker mState.mUsage = usage;
1128*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_USAGE);
1129*8975f5c5SAndroid Build Coastguard Worker }
1130*8975f5c5SAndroid Build Coastguard Worker
getUsage() const1131*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getUsage() const
1132*8975f5c5SAndroid Build Coastguard Worker {
1133*8975f5c5SAndroid Build Coastguard Worker return mState.mUsage;
1134*8975f5c5SAndroid Build Coastguard Worker }
1135*8975f5c5SAndroid Build Coastguard Worker
setProtectedContent(Context * context,bool hasProtectedContent)1136*8975f5c5SAndroid Build Coastguard Worker void Texture::setProtectedContent(Context *context, bool hasProtectedContent)
1137*8975f5c5SAndroid Build Coastguard Worker {
1138*8975f5c5SAndroid Build Coastguard Worker mState.mHasProtectedContent = hasProtectedContent;
1139*8975f5c5SAndroid Build Coastguard Worker }
1140*8975f5c5SAndroid Build Coastguard Worker
hasProtectedContent() const1141*8975f5c5SAndroid Build Coastguard Worker bool Texture::hasProtectedContent() const
1142*8975f5c5SAndroid Build Coastguard Worker {
1143*8975f5c5SAndroid Build Coastguard Worker return mState.mHasProtectedContent;
1144*8975f5c5SAndroid Build Coastguard Worker }
1145*8975f5c5SAndroid Build Coastguard Worker
setRenderabilityValidation(Context * context,bool renderabilityValidation)1146*8975f5c5SAndroid Build Coastguard Worker void Texture::setRenderabilityValidation(Context *context, bool renderabilityValidation)
1147*8975f5c5SAndroid Build Coastguard Worker {
1148*8975f5c5SAndroid Build Coastguard Worker mState.mRenderabilityValidation = renderabilityValidation;
1149*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_RENDERABILITY_VALIDATION_ANGLE);
1150*8975f5c5SAndroid Build Coastguard Worker }
1151*8975f5c5SAndroid Build Coastguard Worker
setTilingMode(Context * context,GLenum tilingMode)1152*8975f5c5SAndroid Build Coastguard Worker void Texture::setTilingMode(Context *context, GLenum tilingMode)
1153*8975f5c5SAndroid Build Coastguard Worker {
1154*8975f5c5SAndroid Build Coastguard Worker mState.mTilingMode = gl::FromGLenum<gl::TilingMode>(tilingMode);
1155*8975f5c5SAndroid Build Coastguard Worker }
1156*8975f5c5SAndroid Build Coastguard Worker
getTilingMode() const1157*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getTilingMode() const
1158*8975f5c5SAndroid Build Coastguard Worker {
1159*8975f5c5SAndroid Build Coastguard Worker return gl::ToGLenum(mState.mTilingMode);
1160*8975f5c5SAndroid Build Coastguard Worker }
1161*8975f5c5SAndroid Build Coastguard Worker
getTextureState() const1162*8975f5c5SAndroid Build Coastguard Worker const TextureState &Texture::getTextureState() const
1163*8975f5c5SAndroid Build Coastguard Worker {
1164*8975f5c5SAndroid Build Coastguard Worker return mState;
1165*8975f5c5SAndroid Build Coastguard Worker }
1166*8975f5c5SAndroid Build Coastguard Worker
getExtents(TextureTarget target,size_t level) const1167*8975f5c5SAndroid Build Coastguard Worker const Extents &Texture::getExtents(TextureTarget target, size_t level) const
1168*8975f5c5SAndroid Build Coastguard Worker {
1169*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1170*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).size;
1171*8975f5c5SAndroid Build Coastguard Worker }
1172*8975f5c5SAndroid Build Coastguard Worker
getWidth(TextureTarget target,size_t level) const1173*8975f5c5SAndroid Build Coastguard Worker size_t Texture::getWidth(TextureTarget target, size_t level) const
1174*8975f5c5SAndroid Build Coastguard Worker {
1175*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1176*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).size.width;
1177*8975f5c5SAndroid Build Coastguard Worker }
1178*8975f5c5SAndroid Build Coastguard Worker
getHeight(TextureTarget target,size_t level) const1179*8975f5c5SAndroid Build Coastguard Worker size_t Texture::getHeight(TextureTarget target, size_t level) const
1180*8975f5c5SAndroid Build Coastguard Worker {
1181*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1182*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).size.height;
1183*8975f5c5SAndroid Build Coastguard Worker }
1184*8975f5c5SAndroid Build Coastguard Worker
getDepth(TextureTarget target,size_t level) const1185*8975f5c5SAndroid Build Coastguard Worker size_t Texture::getDepth(TextureTarget target, size_t level) const
1186*8975f5c5SAndroid Build Coastguard Worker {
1187*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1188*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).size.depth;
1189*8975f5c5SAndroid Build Coastguard Worker }
1190*8975f5c5SAndroid Build Coastguard Worker
getFormat(TextureTarget target,size_t level) const1191*8975f5c5SAndroid Build Coastguard Worker const Format &Texture::getFormat(TextureTarget target, size_t level) const
1192*8975f5c5SAndroid Build Coastguard Worker {
1193*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1194*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).format;
1195*8975f5c5SAndroid Build Coastguard Worker }
1196*8975f5c5SAndroid Build Coastguard Worker
getSamples(TextureTarget target,size_t level) const1197*8975f5c5SAndroid Build Coastguard Worker GLsizei Texture::getSamples(TextureTarget target, size_t level) const
1198*8975f5c5SAndroid Build Coastguard Worker {
1199*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1200*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).samples;
1201*8975f5c5SAndroid Build Coastguard Worker }
1202*8975f5c5SAndroid Build Coastguard Worker
getFixedSampleLocations(TextureTarget target,size_t level) const1203*8975f5c5SAndroid Build Coastguard Worker bool Texture::getFixedSampleLocations(TextureTarget target, size_t level) const
1204*8975f5c5SAndroid Build Coastguard Worker {
1205*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1206*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).fixedSampleLocations;
1207*8975f5c5SAndroid Build Coastguard Worker }
1208*8975f5c5SAndroid Build Coastguard Worker
getMipmapMaxLevel() const1209*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getMipmapMaxLevel() const
1210*8975f5c5SAndroid Build Coastguard Worker {
1211*8975f5c5SAndroid Build Coastguard Worker return mState.getMipmapMaxLevel();
1212*8975f5c5SAndroid Build Coastguard Worker }
1213*8975f5c5SAndroid Build Coastguard Worker
isMipmapComplete() const1214*8975f5c5SAndroid Build Coastguard Worker bool Texture::isMipmapComplete() const
1215*8975f5c5SAndroid Build Coastguard Worker {
1216*8975f5c5SAndroid Build Coastguard Worker return mState.computeMipmapCompleteness();
1217*8975f5c5SAndroid Build Coastguard Worker }
1218*8975f5c5SAndroid Build Coastguard Worker
getFoveatedFeatureBits() const1219*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getFoveatedFeatureBits() const
1220*8975f5c5SAndroid Build Coastguard Worker {
1221*8975f5c5SAndroid Build Coastguard Worker return mState.mFoveationState.getFoveatedFeatureBits();
1222*8975f5c5SAndroid Build Coastguard Worker }
1223*8975f5c5SAndroid Build Coastguard Worker
setFoveatedFeatureBits(const GLuint features)1224*8975f5c5SAndroid Build Coastguard Worker void Texture::setFoveatedFeatureBits(const GLuint features)
1225*8975f5c5SAndroid Build Coastguard Worker {
1226*8975f5c5SAndroid Build Coastguard Worker mState.mFoveationState.setFoveatedFeatureBits(features);
1227*8975f5c5SAndroid Build Coastguard Worker }
1228*8975f5c5SAndroid Build Coastguard Worker
isFoveationEnabled() const1229*8975f5c5SAndroid Build Coastguard Worker bool Texture::isFoveationEnabled() const
1230*8975f5c5SAndroid Build Coastguard Worker {
1231*8975f5c5SAndroid Build Coastguard Worker return (mState.mFoveationState.getFoveatedFeatureBits() & GL_FOVEATION_ENABLE_BIT_QCOM);
1232*8975f5c5SAndroid Build Coastguard Worker }
1233*8975f5c5SAndroid Build Coastguard Worker
getSupportedFoveationFeatures() const1234*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getSupportedFoveationFeatures() const
1235*8975f5c5SAndroid Build Coastguard Worker {
1236*8975f5c5SAndroid Build Coastguard Worker return mState.mFoveationState.getSupportedFoveationFeatures();
1237*8975f5c5SAndroid Build Coastguard Worker }
1238*8975f5c5SAndroid Build Coastguard Worker
getMinPixelDensity() const1239*8975f5c5SAndroid Build Coastguard Worker GLfloat Texture::getMinPixelDensity() const
1240*8975f5c5SAndroid Build Coastguard Worker {
1241*8975f5c5SAndroid Build Coastguard Worker return mState.mFoveationState.getMinPixelDensity();
1242*8975f5c5SAndroid Build Coastguard Worker }
1243*8975f5c5SAndroid Build Coastguard Worker
setMinPixelDensity(const GLfloat density)1244*8975f5c5SAndroid Build Coastguard Worker void Texture::setMinPixelDensity(const GLfloat density)
1245*8975f5c5SAndroid Build Coastguard Worker {
1246*8975f5c5SAndroid Build Coastguard Worker mState.mFoveationState.setMinPixelDensity(density);
1247*8975f5c5SAndroid Build Coastguard Worker }
1248*8975f5c5SAndroid Build Coastguard Worker
setFocalPoint(uint32_t layer,uint32_t focalPointIndex,float focalX,float focalY,float gainX,float gainY,float foveaArea)1249*8975f5c5SAndroid Build Coastguard Worker void Texture::setFocalPoint(uint32_t layer,
1250*8975f5c5SAndroid Build Coastguard Worker uint32_t focalPointIndex,
1251*8975f5c5SAndroid Build Coastguard Worker float focalX,
1252*8975f5c5SAndroid Build Coastguard Worker float focalY,
1253*8975f5c5SAndroid Build Coastguard Worker float gainX,
1254*8975f5c5SAndroid Build Coastguard Worker float gainY,
1255*8975f5c5SAndroid Build Coastguard Worker float foveaArea)
1256*8975f5c5SAndroid Build Coastguard Worker {
1257*8975f5c5SAndroid Build Coastguard Worker gl::FocalPoint newFocalPoint(focalX, focalY, gainX, gainY, foveaArea);
1258*8975f5c5SAndroid Build Coastguard Worker if (mState.mFoveationState.getFocalPoint(layer, focalPointIndex) == newFocalPoint)
1259*8975f5c5SAndroid Build Coastguard Worker {
1260*8975f5c5SAndroid Build Coastguard Worker // Nothing to do, early out.
1261*8975f5c5SAndroid Build Coastguard Worker return;
1262*8975f5c5SAndroid Build Coastguard Worker }
1263*8975f5c5SAndroid Build Coastguard Worker
1264*8975f5c5SAndroid Build Coastguard Worker mState.mFoveationState.setFocalPoint(layer, focalPointIndex, newFocalPoint);
1265*8975f5c5SAndroid Build Coastguard Worker mState.mFoveationState.setFoveatedFeatureBits(GL_FOVEATION_ENABLE_BIT_QCOM);
1266*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::FoveatedRenderingStateChanged);
1267*8975f5c5SAndroid Build Coastguard Worker }
1268*8975f5c5SAndroid Build Coastguard Worker
getFocalPoint(uint32_t layer,uint32_t focalPoint) const1269*8975f5c5SAndroid Build Coastguard Worker const FocalPoint &Texture::getFocalPoint(uint32_t layer, uint32_t focalPoint) const
1270*8975f5c5SAndroid Build Coastguard Worker {
1271*8975f5c5SAndroid Build Coastguard Worker return mState.mFoveationState.getFocalPoint(layer, focalPoint);
1272*8975f5c5SAndroid Build Coastguard Worker }
1273*8975f5c5SAndroid Build Coastguard Worker
getBoundSurface() const1274*8975f5c5SAndroid Build Coastguard Worker egl::Surface *Texture::getBoundSurface() const
1275*8975f5c5SAndroid Build Coastguard Worker {
1276*8975f5c5SAndroid Build Coastguard Worker return mBoundSurface;
1277*8975f5c5SAndroid Build Coastguard Worker }
1278*8975f5c5SAndroid Build Coastguard Worker
getBoundStream() const1279*8975f5c5SAndroid Build Coastguard Worker egl::Stream *Texture::getBoundStream() const
1280*8975f5c5SAndroid Build Coastguard Worker {
1281*8975f5c5SAndroid Build Coastguard Worker return mBoundStream;
1282*8975f5c5SAndroid Build Coastguard Worker }
1283*8975f5c5SAndroid Build Coastguard Worker
getMemorySize() const1284*8975f5c5SAndroid Build Coastguard Worker GLint Texture::getMemorySize() const
1285*8975f5c5SAndroid Build Coastguard Worker {
1286*8975f5c5SAndroid Build Coastguard Worker GLint implSize = mTexture->getMemorySize();
1287*8975f5c5SAndroid Build Coastguard Worker if (implSize > 0)
1288*8975f5c5SAndroid Build Coastguard Worker {
1289*8975f5c5SAndroid Build Coastguard Worker return implSize;
1290*8975f5c5SAndroid Build Coastguard Worker }
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<GLint> size = 0;
1293*8975f5c5SAndroid Build Coastguard Worker for (const ImageDesc &imageDesc : mState.mImageDescs)
1294*8975f5c5SAndroid Build Coastguard Worker {
1295*8975f5c5SAndroid Build Coastguard Worker size += imageDesc.getMemorySize();
1296*8975f5c5SAndroid Build Coastguard Worker }
1297*8975f5c5SAndroid Build Coastguard Worker return size.ValueOrDefault(std::numeric_limits<GLint>::max());
1298*8975f5c5SAndroid Build Coastguard Worker }
1299*8975f5c5SAndroid Build Coastguard Worker
getLevelMemorySize(TextureTarget target,GLint level) const1300*8975f5c5SAndroid Build Coastguard Worker GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const
1301*8975f5c5SAndroid Build Coastguard Worker {
1302*8975f5c5SAndroid Build Coastguard Worker GLint implSize = mTexture->getLevelMemorySize(target, level);
1303*8975f5c5SAndroid Build Coastguard Worker if (implSize > 0)
1304*8975f5c5SAndroid Build Coastguard Worker {
1305*8975f5c5SAndroid Build Coastguard Worker return implSize;
1306*8975f5c5SAndroid Build Coastguard Worker }
1307*8975f5c5SAndroid Build Coastguard Worker
1308*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(target, level).getMemorySize();
1309*8975f5c5SAndroid Build Coastguard Worker }
1310*8975f5c5SAndroid Build Coastguard Worker
signalDirtyStorage(InitState initState)1311*8975f5c5SAndroid Build Coastguard Worker void Texture::signalDirtyStorage(InitState initState)
1312*8975f5c5SAndroid Build Coastguard Worker {
1313*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = initState;
1314*8975f5c5SAndroid Build Coastguard Worker invalidateCompletenessCache();
1315*8975f5c5SAndroid Build Coastguard Worker mState.mCachedSamplerFormatValid = false;
1316*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::SubjectChanged);
1317*8975f5c5SAndroid Build Coastguard Worker }
1318*8975f5c5SAndroid Build Coastguard Worker
signalDirtyState(size_t dirtyBit)1319*8975f5c5SAndroid Build Coastguard Worker void Texture::signalDirtyState(size_t dirtyBit)
1320*8975f5c5SAndroid Build Coastguard Worker {
1321*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(dirtyBit);
1322*8975f5c5SAndroid Build Coastguard Worker invalidateCompletenessCache();
1323*8975f5c5SAndroid Build Coastguard Worker mState.mCachedSamplerFormatValid = false;
1324*8975f5c5SAndroid Build Coastguard Worker
1325*8975f5c5SAndroid Build Coastguard Worker if (dirtyBit == DIRTY_BIT_BASE_LEVEL || dirtyBit == DIRTY_BIT_MAX_LEVEL)
1326*8975f5c5SAndroid Build Coastguard Worker {
1327*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::SubjectChanged);
1328*8975f5c5SAndroid Build Coastguard Worker }
1329*8975f5c5SAndroid Build Coastguard Worker else
1330*8975f5c5SAndroid Build Coastguard Worker {
1331*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1332*8975f5c5SAndroid Build Coastguard Worker }
1333*8975f5c5SAndroid Build Coastguard Worker }
1334*8975f5c5SAndroid Build Coastguard Worker
setImage(Context * context,const PixelUnpackState & unpackState,Buffer * unpackBuffer,TextureTarget target,GLint level,GLenum internalFormat,const Extents & size,GLenum format,GLenum type,const uint8_t * pixels)1335*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setImage(Context *context,
1336*8975f5c5SAndroid Build Coastguard Worker const PixelUnpackState &unpackState,
1337*8975f5c5SAndroid Build Coastguard Worker Buffer *unpackBuffer,
1338*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1339*8975f5c5SAndroid Build Coastguard Worker GLint level,
1340*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1341*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1342*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1343*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1344*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1345*8975f5c5SAndroid Build Coastguard Worker {
1346*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1347*8975f5c5SAndroid Build Coastguard Worker
1348*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1349*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1350*8975f5c5SAndroid Build Coastguard Worker
1351*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1352*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1353*8975f5c5SAndroid Build Coastguard Worker
1354*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
1355*8975f5c5SAndroid Build Coastguard Worker
1356*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size, format, type, unpackState,
1357*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, pixels));
1358*8975f5c5SAndroid Build Coastguard Worker
1359*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, unpackBuffer, pixels);
1360*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
1361*8975f5c5SAndroid Build Coastguard Worker
1362*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
1363*8975f5c5SAndroid Build Coastguard Worker
1364*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1365*8975f5c5SAndroid Build Coastguard Worker
1366*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1367*8975f5c5SAndroid Build Coastguard Worker }
1368*8975f5c5SAndroid Build Coastguard Worker
setSubImage(Context * context,const PixelUnpackState & unpackState,Buffer * unpackBuffer,TextureTarget target,GLint level,const Box & area,GLenum format,GLenum type,const uint8_t * pixels)1369*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setSubImage(Context *context,
1370*8975f5c5SAndroid Build Coastguard Worker const PixelUnpackState &unpackState,
1371*8975f5c5SAndroid Build Coastguard Worker Buffer *unpackBuffer,
1372*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1373*8975f5c5SAndroid Build Coastguard Worker GLint level,
1374*8975f5c5SAndroid Build Coastguard Worker const Box &area,
1375*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1376*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1377*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1378*8975f5c5SAndroid Build Coastguard Worker {
1379*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1380*8975f5c5SAndroid Build Coastguard Worker
1381*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth);
1382*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, area));
1383*8975f5c5SAndroid Build Coastguard Worker
1384*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setSubImage(context, index, area, format, type, unpackState, unpackBuffer,
1385*8975f5c5SAndroid Build Coastguard Worker pixels));
1386*8975f5c5SAndroid Build Coastguard Worker
1387*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
1388*8975f5c5SAndroid Build Coastguard Worker
1389*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
1390*8975f5c5SAndroid Build Coastguard Worker
1391*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1392*8975f5c5SAndroid Build Coastguard Worker }
1393*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(Context * context,const PixelUnpackState & unpackState,TextureTarget target,GLint level,GLenum internalFormat,const Extents & size,size_t imageSize,const uint8_t * pixels)1394*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setCompressedImage(Context *context,
1395*8975f5c5SAndroid Build Coastguard Worker const PixelUnpackState &unpackState,
1396*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1397*8975f5c5SAndroid Build Coastguard Worker GLint level,
1398*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1399*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1400*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1401*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1402*8975f5c5SAndroid Build Coastguard Worker {
1403*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1404*8975f5c5SAndroid Build Coastguard Worker
1405*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1406*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1407*8975f5c5SAndroid Build Coastguard Worker
1408*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1409*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1410*8975f5c5SAndroid Build Coastguard Worker
1411*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
1412*8975f5c5SAndroid Build Coastguard Worker
1413*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setCompressedImage(context, index, internalFormat, size, unpackState,
1414*8975f5c5SAndroid Build Coastguard Worker imageSize, pixels));
1415*8975f5c5SAndroid Build Coastguard Worker
1416*8975f5c5SAndroid Build Coastguard Worker Buffer *unpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
1417*8975f5c5SAndroid Build Coastguard Worker
1418*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, unpackBuffer, pixels);
1419*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState));
1420*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1421*8975f5c5SAndroid Build Coastguard Worker
1422*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1423*8975f5c5SAndroid Build Coastguard Worker }
1424*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const Context * context,const PixelUnpackState & unpackState,TextureTarget target,GLint level,const Box & area,GLenum format,size_t imageSize,const uint8_t * pixels)1425*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setCompressedSubImage(const Context *context,
1426*8975f5c5SAndroid Build Coastguard Worker const PixelUnpackState &unpackState,
1427*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1428*8975f5c5SAndroid Build Coastguard Worker GLint level,
1429*8975f5c5SAndroid Build Coastguard Worker const Box &area,
1430*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1431*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
1432*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
1433*8975f5c5SAndroid Build Coastguard Worker {
1434*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1435*8975f5c5SAndroid Build Coastguard Worker
1436*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth);
1437*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, area));
1438*8975f5c5SAndroid Build Coastguard Worker
1439*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setCompressedSubImage(context, index, area, format, unpackState, imageSize,
1440*8975f5c5SAndroid Build Coastguard Worker pixels));
1441*8975f5c5SAndroid Build Coastguard Worker
1442*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
1443*8975f5c5SAndroid Build Coastguard Worker
1444*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1445*8975f5c5SAndroid Build Coastguard Worker }
1446*8975f5c5SAndroid Build Coastguard Worker
copyImage(Context * context,TextureTarget target,GLint level,const Rectangle & sourceArea,GLenum internalFormat,Framebuffer * source)1447*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copyImage(Context *context,
1448*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1449*8975f5c5SAndroid Build Coastguard Worker GLint level,
1450*8975f5c5SAndroid Build Coastguard Worker const Rectangle &sourceArea,
1451*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1452*8975f5c5SAndroid Build Coastguard Worker Framebuffer *source)
1453*8975f5c5SAndroid Build Coastguard Worker {
1454*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1455*8975f5c5SAndroid Build Coastguard Worker
1456*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1457*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1458*8975f5c5SAndroid Build Coastguard Worker
1459*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1460*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1461*8975f5c5SAndroid Build Coastguard Worker
1462*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
1463*8975f5c5SAndroid Build Coastguard Worker
1464*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &internalFormatInfo =
1465*8975f5c5SAndroid Build Coastguard Worker GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
1466*8975f5c5SAndroid Build Coastguard Worker
1467*8975f5c5SAndroid Build Coastguard Worker // Most if not all renderers clip these copies to the size of the source framebuffer, leaving
1468*8975f5c5SAndroid Build Coastguard Worker // other pixels untouched. For safety in robust resource initialization, assume that that
1469*8975f5c5SAndroid Build Coastguard Worker // clipping is going to occur when computing the region for which to ensure initialization. If
1470*8975f5c5SAndroid Build Coastguard Worker // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is
1471*8975f5c5SAndroid Build Coastguard Worker // going to be set during the copy operation.
1472*8975f5c5SAndroid Build Coastguard Worker Box destBox;
1473*8975f5c5SAndroid Build Coastguard Worker bool forceCopySubImage = false;
1474*8975f5c5SAndroid Build Coastguard Worker if (context->isRobustResourceInitEnabled())
1475*8975f5c5SAndroid Build Coastguard Worker {
1476*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *sourceReadAttachment = source->getReadColorAttachment();
1477*8975f5c5SAndroid Build Coastguard Worker Extents fbSize = sourceReadAttachment->getSize();
1478*8975f5c5SAndroid Build Coastguard Worker // Force using copySubImage when the source area is out of bounds AND
1479*8975f5c5SAndroid Build Coastguard Worker // we're not copying to and from the same texture
1480*8975f5c5SAndroid Build Coastguard Worker forceCopySubImage = ((sourceArea.x < 0) || (sourceArea.y < 0) ||
1481*8975f5c5SAndroid Build Coastguard Worker ((sourceArea.x + sourceArea.width) > fbSize.width) ||
1482*8975f5c5SAndroid Build Coastguard Worker ((sourceArea.y + sourceArea.height) > fbSize.height)) &&
1483*8975f5c5SAndroid Build Coastguard Worker (sourceReadAttachment->getResource() != this);
1484*8975f5c5SAndroid Build Coastguard Worker Rectangle clippedArea;
1485*8975f5c5SAndroid Build Coastguard Worker if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1486*8975f5c5SAndroid Build Coastguard Worker {
1487*8975f5c5SAndroid Build Coastguard Worker const Offset clippedOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y,
1488*8975f5c5SAndroid Build Coastguard Worker 0);
1489*8975f5c5SAndroid Build Coastguard Worker destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width,
1490*8975f5c5SAndroid Build Coastguard Worker clippedArea.height, 1);
1491*8975f5c5SAndroid Build Coastguard Worker }
1492*8975f5c5SAndroid Build Coastguard Worker }
1493*8975f5c5SAndroid Build Coastguard Worker
1494*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, nullptr, nullptr);
1495*8975f5c5SAndroid Build Coastguard Worker
1496*8975f5c5SAndroid Build Coastguard Worker // If we need to initialize the destination texture we split the call into a create call,
1497*8975f5c5SAndroid Build Coastguard Worker // an initializeContents call, and then a copySubImage call. This ensures the destination
1498*8975f5c5SAndroid Build Coastguard Worker // texture exists before we try to clear it.
1499*8975f5c5SAndroid Build Coastguard Worker Extents size(sourceArea.width, sourceArea.height, 1);
1500*8975f5c5SAndroid Build Coastguard Worker if (forceCopySubImage || doesSubImageNeedInit(context, index, destBox))
1501*8975f5c5SAndroid Build Coastguard Worker {
1502*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size,
1503*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.format, internalFormatInfo.type,
1504*8975f5c5SAndroid Build Coastguard Worker PixelUnpackState(), nullptr, nullptr));
1505*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormatInfo), initState));
1506*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
1507*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copySubImage(context, index, Offset(), sourceArea, source));
1508*8975f5c5SAndroid Build Coastguard Worker }
1509*8975f5c5SAndroid Build Coastguard Worker else
1510*8975f5c5SAndroid Build Coastguard Worker {
1511*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copyImage(context, index, sourceArea, internalFormat, source));
1512*8975f5c5SAndroid Build Coastguard Worker }
1513*8975f5c5SAndroid Build Coastguard Worker
1514*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(target, level,
1515*8975f5c5SAndroid Build Coastguard Worker ImageDesc(size, Format(internalFormatInfo), InitState::Initialized));
1516*8975f5c5SAndroid Build Coastguard Worker
1517*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
1518*8975f5c5SAndroid Build Coastguard Worker
1519*8975f5c5SAndroid Build Coastguard Worker // Because this could affect the texture storage we might need to init other layers/levels.
1520*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1521*8975f5c5SAndroid Build Coastguard Worker
1522*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1523*8975f5c5SAndroid Build Coastguard Worker }
1524*8975f5c5SAndroid Build Coastguard Worker
copySubImage(Context * context,const ImageIndex & index,const Offset & destOffset,const Rectangle & sourceArea,Framebuffer * source)1525*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copySubImage(Context *context,
1526*8975f5c5SAndroid Build Coastguard Worker const ImageIndex &index,
1527*8975f5c5SAndroid Build Coastguard Worker const Offset &destOffset,
1528*8975f5c5SAndroid Build Coastguard Worker const Rectangle &sourceArea,
1529*8975f5c5SAndroid Build Coastguard Worker Framebuffer *source)
1530*8975f5c5SAndroid Build Coastguard Worker {
1531*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(index.getTarget()) == mState.mType);
1532*8975f5c5SAndroid Build Coastguard Worker
1533*8975f5c5SAndroid Build Coastguard Worker // Most if not all renderers clip these copies to the size of the source framebuffer, leaving
1534*8975f5c5SAndroid Build Coastguard Worker // other pixels untouched. For safety in robust resource initialization, assume that that
1535*8975f5c5SAndroid Build Coastguard Worker // clipping is going to occur when computing the region for which to ensure initialization. If
1536*8975f5c5SAndroid Build Coastguard Worker // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is
1537*8975f5c5SAndroid Build Coastguard Worker // going to be set during the copy operation. Note that this assumes that
1538*8975f5c5SAndroid Build Coastguard Worker // ensureSubImageInitialized ensures initialization of the entire destination texture, and not
1539*8975f5c5SAndroid Build Coastguard Worker // just a sub-region.
1540*8975f5c5SAndroid Build Coastguard Worker Box destBox;
1541*8975f5c5SAndroid Build Coastguard Worker if (context->isRobustResourceInitEnabled())
1542*8975f5c5SAndroid Build Coastguard Worker {
1543*8975f5c5SAndroid Build Coastguard Worker Extents fbSize = source->getReadColorAttachment()->getSize();
1544*8975f5c5SAndroid Build Coastguard Worker Rectangle clippedArea;
1545*8975f5c5SAndroid Build Coastguard Worker if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
1546*8975f5c5SAndroid Build Coastguard Worker {
1547*8975f5c5SAndroid Build Coastguard Worker const Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
1548*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedArea.y - sourceArea.y, 0);
1549*8975f5c5SAndroid Build Coastguard Worker destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width,
1550*8975f5c5SAndroid Build Coastguard Worker clippedArea.height, 1);
1551*8975f5c5SAndroid Build Coastguard Worker }
1552*8975f5c5SAndroid Build Coastguard Worker }
1553*8975f5c5SAndroid Build Coastguard Worker
1554*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
1555*8975f5c5SAndroid Build Coastguard Worker
1556*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copySubImage(context, index, destOffset, sourceArea, source));
1557*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, index.getLevelIndex()));
1558*8975f5c5SAndroid Build Coastguard Worker
1559*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
1560*8975f5c5SAndroid Build Coastguard Worker
1561*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1562*8975f5c5SAndroid Build Coastguard Worker }
1563*8975f5c5SAndroid Build Coastguard Worker
copyRenderbufferSubData(Context * context,const gl::Renderbuffer * srcBuffer,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1564*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copyRenderbufferSubData(Context *context,
1565*8975f5c5SAndroid Build Coastguard Worker const gl::Renderbuffer *srcBuffer,
1566*8975f5c5SAndroid Build Coastguard Worker GLint srcLevel,
1567*8975f5c5SAndroid Build Coastguard Worker GLint srcX,
1568*8975f5c5SAndroid Build Coastguard Worker GLint srcY,
1569*8975f5c5SAndroid Build Coastguard Worker GLint srcZ,
1570*8975f5c5SAndroid Build Coastguard Worker GLint dstLevel,
1571*8975f5c5SAndroid Build Coastguard Worker GLint dstX,
1572*8975f5c5SAndroid Build Coastguard Worker GLint dstY,
1573*8975f5c5SAndroid Build Coastguard Worker GLint dstZ,
1574*8975f5c5SAndroid Build Coastguard Worker GLsizei srcWidth,
1575*8975f5c5SAndroid Build Coastguard Worker GLsizei srcHeight,
1576*8975f5c5SAndroid Build Coastguard Worker GLsizei srcDepth)
1577*8975f5c5SAndroid Build Coastguard Worker {
1578*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY, srcZ,
1579*8975f5c5SAndroid Build Coastguard Worker dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
1580*8975f5c5SAndroid Build Coastguard Worker srcDepth));
1581*8975f5c5SAndroid Build Coastguard Worker
1582*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
1583*8975f5c5SAndroid Build Coastguard Worker
1584*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1585*8975f5c5SAndroid Build Coastguard Worker }
1586*8975f5c5SAndroid Build Coastguard Worker
copyTextureSubData(Context * context,const gl::Texture * srcTexture,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1587*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copyTextureSubData(Context *context,
1588*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *srcTexture,
1589*8975f5c5SAndroid Build Coastguard Worker GLint srcLevel,
1590*8975f5c5SAndroid Build Coastguard Worker GLint srcX,
1591*8975f5c5SAndroid Build Coastguard Worker GLint srcY,
1592*8975f5c5SAndroid Build Coastguard Worker GLint srcZ,
1593*8975f5c5SAndroid Build Coastguard Worker GLint dstLevel,
1594*8975f5c5SAndroid Build Coastguard Worker GLint dstX,
1595*8975f5c5SAndroid Build Coastguard Worker GLint dstY,
1596*8975f5c5SAndroid Build Coastguard Worker GLint dstZ,
1597*8975f5c5SAndroid Build Coastguard Worker GLsizei srcWidth,
1598*8975f5c5SAndroid Build Coastguard Worker GLsizei srcHeight,
1599*8975f5c5SAndroid Build Coastguard Worker GLsizei srcDepth)
1600*8975f5c5SAndroid Build Coastguard Worker {
1601*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
1602*8975f5c5SAndroid Build Coastguard Worker dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
1603*8975f5c5SAndroid Build Coastguard Worker srcDepth));
1604*8975f5c5SAndroid Build Coastguard Worker
1605*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
1606*8975f5c5SAndroid Build Coastguard Worker
1607*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1608*8975f5c5SAndroid Build Coastguard Worker }
1609*8975f5c5SAndroid Build Coastguard Worker
copyTexture(Context * context,TextureTarget target,GLint level,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,Texture * source)1610*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copyTexture(Context *context,
1611*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1612*8975f5c5SAndroid Build Coastguard Worker GLint level,
1613*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1614*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1615*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1616*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
1617*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
1618*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
1619*8975f5c5SAndroid Build Coastguard Worker Texture *source)
1620*8975f5c5SAndroid Build Coastguard Worker {
1621*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1622*8975f5c5SAndroid Build Coastguard Worker ASSERT(source->getType() != TextureType::CubeMap);
1623*8975f5c5SAndroid Build Coastguard Worker
1624*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1625*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1626*8975f5c5SAndroid Build Coastguard Worker
1627*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1628*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1629*8975f5c5SAndroid Build Coastguard Worker
1630*8975f5c5SAndroid Build Coastguard Worker // Initialize source texture.
1631*8975f5c5SAndroid Build Coastguard Worker // Note: we don't have a way to notify which portions of the image changed currently.
1632*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(source->ensureInitialized(context));
1633*8975f5c5SAndroid Build Coastguard Worker
1634*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, ImageIndex::kEntireLevel);
1635*8975f5c5SAndroid Build Coastguard Worker
1636*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copyTexture(context, index, internalFormat, type, sourceLevel, unpackFlipY,
1637*8975f5c5SAndroid Build Coastguard Worker unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source));
1638*8975f5c5SAndroid Build Coastguard Worker
1639*8975f5c5SAndroid Build Coastguard Worker const auto &sourceDesc =
1640*8975f5c5SAndroid Build Coastguard Worker source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
1641*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
1642*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(
1643*8975f5c5SAndroid Build Coastguard Worker target, level,
1644*8975f5c5SAndroid Build Coastguard Worker ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized));
1645*8975f5c5SAndroid Build Coastguard Worker
1646*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
1647*8975f5c5SAndroid Build Coastguard Worker
1648*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1649*8975f5c5SAndroid Build Coastguard Worker }
1650*8975f5c5SAndroid Build Coastguard Worker
copySubTexture(const Context * context,TextureTarget target,GLint level,const Offset & destOffset,GLint sourceLevel,const Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,Texture * source)1651*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copySubTexture(const Context *context,
1652*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1653*8975f5c5SAndroid Build Coastguard Worker GLint level,
1654*8975f5c5SAndroid Build Coastguard Worker const Offset &destOffset,
1655*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1656*8975f5c5SAndroid Build Coastguard Worker const Box &sourceBox,
1657*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
1658*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
1659*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
1660*8975f5c5SAndroid Build Coastguard Worker Texture *source)
1661*8975f5c5SAndroid Build Coastguard Worker {
1662*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1663*8975f5c5SAndroid Build Coastguard Worker
1664*8975f5c5SAndroid Build Coastguard Worker // Ensure source is initialized.
1665*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(source->ensureInitialized(context));
1666*8975f5c5SAndroid Build Coastguard Worker
1667*8975f5c5SAndroid Build Coastguard Worker Box destBox(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, sourceBox.height,
1668*8975f5c5SAndroid Build Coastguard Worker sourceBox.depth);
1669*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, sourceBox.depth);
1670*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
1671*8975f5c5SAndroid Build Coastguard Worker
1672*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copySubTexture(context, index, destOffset, sourceLevel, sourceBox,
1673*8975f5c5SAndroid Build Coastguard Worker unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha,
1674*8975f5c5SAndroid Build Coastguard Worker source));
1675*8975f5c5SAndroid Build Coastguard Worker
1676*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
1677*8975f5c5SAndroid Build Coastguard Worker
1678*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1679*8975f5c5SAndroid Build Coastguard Worker }
1680*8975f5c5SAndroid Build Coastguard Worker
copyCompressedTexture(Context * context,const Texture * source)1681*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::copyCompressedTexture(Context *context, const Texture *source)
1682*8975f5c5SAndroid Build Coastguard Worker {
1683*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1684*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1685*8975f5c5SAndroid Build Coastguard Worker
1686*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1687*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1688*8975f5c5SAndroid Build Coastguard Worker
1689*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->copyCompressedTexture(context, source));
1690*8975f5c5SAndroid Build Coastguard Worker
1691*8975f5c5SAndroid Build Coastguard Worker ASSERT(source->getType() != TextureType::CubeMap && getType() != TextureType::CubeMap);
1692*8975f5c5SAndroid Build Coastguard Worker const auto &sourceDesc =
1693*8975f5c5SAndroid Build Coastguard Worker source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), 0);
1694*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(NonCubeTextureTypeToTarget(getType()), 0, sourceDesc);
1695*8975f5c5SAndroid Build Coastguard Worker
1696*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1697*8975f5c5SAndroid Build Coastguard Worker }
1698*8975f5c5SAndroid Build Coastguard Worker
setStorage(Context * context,TextureType type,GLsizei levels,GLenum internalFormat,const Extents & size)1699*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setStorage(Context *context,
1700*8975f5c5SAndroid Build Coastguard Worker TextureType type,
1701*8975f5c5SAndroid Build Coastguard Worker GLsizei levels,
1702*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1703*8975f5c5SAndroid Build Coastguard Worker const Extents &size)
1704*8975f5c5SAndroid Build Coastguard Worker {
1705*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == mState.mType);
1706*8975f5c5SAndroid Build Coastguard Worker
1707*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1708*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1709*8975f5c5SAndroid Build Coastguard Worker
1710*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1711*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1712*8975f5c5SAndroid Build Coastguard Worker
1713*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
1714*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = static_cast<GLuint>(levels);
1715*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
1716*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, nullptr, nullptr);
1717*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
1718*8975f5c5SAndroid Build Coastguard Worker initState);
1719*8975f5c5SAndroid Build Coastguard Worker
1720*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setStorage(context, type, levels, internalFormat, size));
1721*8975f5c5SAndroid Build Coastguard Worker
1722*8975f5c5SAndroid Build Coastguard Worker // Changing the texture to immutable can trigger a change in the base and max levels:
1723*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10 pg 158:
1724*8975f5c5SAndroid Build Coastguard Worker // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
1725*8975f5c5SAndroid Build Coastguard Worker // clamped to the range[levelbase;levels].
1726*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
1727*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
1728*8975f5c5SAndroid Build Coastguard Worker
1729*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1730*8975f5c5SAndroid Build Coastguard Worker
1731*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1732*8975f5c5SAndroid Build Coastguard Worker }
1733*8975f5c5SAndroid Build Coastguard Worker
setImageExternal(Context * context,TextureTarget target,GLint level,GLenum internalFormat,const Extents & size,GLenum format,GLenum type)1734*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setImageExternal(Context *context,
1735*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
1736*8975f5c5SAndroid Build Coastguard Worker GLint level,
1737*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1738*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1739*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1740*8975f5c5SAndroid Build Coastguard Worker GLenum type)
1741*8975f5c5SAndroid Build Coastguard Worker {
1742*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == mState.mType);
1743*8975f5c5SAndroid Build Coastguard Worker
1744*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1745*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1746*8975f5c5SAndroid Build Coastguard Worker
1747*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1748*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1749*8975f5c5SAndroid Build Coastguard Worker
1750*8975f5c5SAndroid Build Coastguard Worker ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
1751*8975f5c5SAndroid Build Coastguard Worker
1752*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setImageExternal(context, index, internalFormat, size, format, type));
1753*8975f5c5SAndroid Build Coastguard Worker
1754*8975f5c5SAndroid Build Coastguard Worker InitState initState = InitState::Initialized;
1755*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
1756*8975f5c5SAndroid Build Coastguard Worker
1757*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
1758*8975f5c5SAndroid Build Coastguard Worker
1759*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1760*8975f5c5SAndroid Build Coastguard Worker
1761*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1762*8975f5c5SAndroid Build Coastguard Worker }
1763*8975f5c5SAndroid Build Coastguard Worker
setStorageMultisample(Context * context,TextureType type,GLsizei samplesIn,GLint internalFormat,const Extents & size,bool fixedSampleLocations)1764*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setStorageMultisample(Context *context,
1765*8975f5c5SAndroid Build Coastguard Worker TextureType type,
1766*8975f5c5SAndroid Build Coastguard Worker GLsizei samplesIn,
1767*8975f5c5SAndroid Build Coastguard Worker GLint internalFormat,
1768*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1769*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations)
1770*8975f5c5SAndroid Build Coastguard Worker {
1771*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == mState.mType);
1772*8975f5c5SAndroid Build Coastguard Worker
1773*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1774*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1775*8975f5c5SAndroid Build Coastguard Worker
1776*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1777*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1778*8975f5c5SAndroid Build Coastguard Worker
1779*8975f5c5SAndroid Build Coastguard Worker // Potentially adjust "samples" to a supported value
1780*8975f5c5SAndroid Build Coastguard Worker const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
1781*8975f5c5SAndroid Build Coastguard Worker GLsizei samples = formatCaps.getNearestSamples(samplesIn);
1782*8975f5c5SAndroid Build Coastguard Worker
1783*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
1784*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = static_cast<GLuint>(1);
1785*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
1786*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, nullptr, nullptr);
1787*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations,
1788*8975f5c5SAndroid Build Coastguard Worker initState);
1789*8975f5c5SAndroid Build Coastguard Worker
1790*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setStorageMultisample(context, type, samples, internalFormat, size,
1791*8975f5c5SAndroid Build Coastguard Worker fixedSampleLocations));
1792*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1793*8975f5c5SAndroid Build Coastguard Worker
1794*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1795*8975f5c5SAndroid Build Coastguard Worker }
1796*8975f5c5SAndroid Build Coastguard Worker
setStorageExternalMemory(Context * context,TextureType type,GLsizei levels,GLenum internalFormat,const Extents & size,MemoryObject * memoryObject,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)1797*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setStorageExternalMemory(Context *context,
1798*8975f5c5SAndroid Build Coastguard Worker TextureType type,
1799*8975f5c5SAndroid Build Coastguard Worker GLsizei levels,
1800*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1801*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1802*8975f5c5SAndroid Build Coastguard Worker MemoryObject *memoryObject,
1803*8975f5c5SAndroid Build Coastguard Worker GLuint64 offset,
1804*8975f5c5SAndroid Build Coastguard Worker GLbitfield createFlags,
1805*8975f5c5SAndroid Build Coastguard Worker GLbitfield usageFlags,
1806*8975f5c5SAndroid Build Coastguard Worker const void *imageCreateInfoPNext)
1807*8975f5c5SAndroid Build Coastguard Worker {
1808*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == mState.mType);
1809*8975f5c5SAndroid Build Coastguard Worker
1810*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1811*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1812*8975f5c5SAndroid Build Coastguard Worker
1813*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1814*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1815*8975f5c5SAndroid Build Coastguard Worker
1816*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setStorageExternalMemory(context, type, levels, internalFormat, size,
1817*8975f5c5SAndroid Build Coastguard Worker memoryObject, offset, createFlags, usageFlags,
1818*8975f5c5SAndroid Build Coastguard Worker imageCreateInfoPNext));
1819*8975f5c5SAndroid Build Coastguard Worker
1820*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
1821*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = static_cast<GLuint>(levels);
1822*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
1823*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
1824*8975f5c5SAndroid Build Coastguard Worker InitState::Initialized);
1825*8975f5c5SAndroid Build Coastguard Worker
1826*8975f5c5SAndroid Build Coastguard Worker // Changing the texture to immutable can trigger a change in the base and max levels:
1827*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10 pg 158:
1828*8975f5c5SAndroid Build Coastguard Worker // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
1829*8975f5c5SAndroid Build Coastguard Worker // clamped to the range[levelbase;levels].
1830*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
1831*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
1832*8975f5c5SAndroid Build Coastguard Worker
1833*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
1834*8975f5c5SAndroid Build Coastguard Worker
1835*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1836*8975f5c5SAndroid Build Coastguard Worker }
1837*8975f5c5SAndroid Build Coastguard Worker
setStorageAttribs(Context * context,TextureType type,GLsizei levels,GLenum internalFormat,const Extents & size,const GLint * attribList)1838*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setStorageAttribs(Context *context,
1839*8975f5c5SAndroid Build Coastguard Worker TextureType type,
1840*8975f5c5SAndroid Build Coastguard Worker GLsizei levels,
1841*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1842*8975f5c5SAndroid Build Coastguard Worker const Extents &size,
1843*8975f5c5SAndroid Build Coastguard Worker const GLint *attribList)
1844*8975f5c5SAndroid Build Coastguard Worker {
1845*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == mState.mType);
1846*8975f5c5SAndroid Build Coastguard Worker
1847*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1848*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1849*8975f5c5SAndroid Build Coastguard Worker
1850*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1851*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1852*8975f5c5SAndroid Build Coastguard Worker
1853*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
1854*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = static_cast<GLuint>(levels);
1855*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
1856*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, nullptr, nullptr);
1857*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
1858*8975f5c5SAndroid Build Coastguard Worker initState);
1859*8975f5c5SAndroid Build Coastguard Worker
1860*8975f5c5SAndroid Build Coastguard Worker if (nullptr != attribList && GL_SURFACE_COMPRESSION_EXT == *attribList)
1861*8975f5c5SAndroid Build Coastguard Worker {
1862*8975f5c5SAndroid Build Coastguard Worker attribList++;
1863*8975f5c5SAndroid Build Coastguard Worker if (nullptr != attribList && GL_NONE != *attribList)
1864*8975f5c5SAndroid Build Coastguard Worker {
1865*8975f5c5SAndroid Build Coastguard Worker mState.mCompressionFixedRate = *attribList;
1866*8975f5c5SAndroid Build Coastguard Worker }
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker
1869*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setStorageAttribs(context, type, levels, internalFormat, size, attribList));
1870*8975f5c5SAndroid Build Coastguard Worker
1871*8975f5c5SAndroid Build Coastguard Worker // Changing the texture to immutable can trigger a change in the base and max levels:
1872*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10 pg 158:
1873*8975f5c5SAndroid Build Coastguard Worker // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
1874*8975f5c5SAndroid Build Coastguard Worker // clamped to the range[levelbase;levels].
1875*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
1876*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
1877*8975f5c5SAndroid Build Coastguard Worker
1878*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
1879*8975f5c5SAndroid Build Coastguard Worker
1880*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1881*8975f5c5SAndroid Build Coastguard Worker }
1882*8975f5c5SAndroid Build Coastguard Worker
getImageCompressionRate(const Context * context) const1883*8975f5c5SAndroid Build Coastguard Worker GLint Texture::getImageCompressionRate(const Context *context) const
1884*8975f5c5SAndroid Build Coastguard Worker {
1885*8975f5c5SAndroid Build Coastguard Worker return mTexture->getImageCompressionRate(context);
1886*8975f5c5SAndroid Build Coastguard Worker }
1887*8975f5c5SAndroid Build Coastguard Worker
getFormatSupportedCompressionRates(const Context * context,GLenum internalformat,GLsizei bufSize,GLint * rates) const1888*8975f5c5SAndroid Build Coastguard Worker GLint Texture::getFormatSupportedCompressionRates(const Context *context,
1889*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
1890*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
1891*8975f5c5SAndroid Build Coastguard Worker GLint *rates) const
1892*8975f5c5SAndroid Build Coastguard Worker {
1893*8975f5c5SAndroid Build Coastguard Worker return mTexture->getFormatSupportedCompressionRates(context, internalformat, bufSize, rates);
1894*8975f5c5SAndroid Build Coastguard Worker }
1895*8975f5c5SAndroid Build Coastguard Worker
generateMipmap(Context * context)1896*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::generateMipmap(Context *context)
1897*8975f5c5SAndroid Build Coastguard Worker {
1898*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
1899*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
1900*8975f5c5SAndroid Build Coastguard Worker
1901*8975f5c5SAndroid Build Coastguard Worker // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture
1902*8975f5c5SAndroid Build Coastguard Worker // is not mip complete.
1903*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
1904*8975f5c5SAndroid Build Coastguard Worker if (!isMipmapComplete())
1905*8975f5c5SAndroid Build Coastguard Worker {
1906*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
1907*8975f5c5SAndroid Build Coastguard Worker }
1908*8975f5c5SAndroid Build Coastguard Worker
1909*8975f5c5SAndroid Build Coastguard Worker const GLuint baseLevel = mState.getEffectiveBaseLevel();
1910*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
1911*8975f5c5SAndroid Build Coastguard Worker
1912*8975f5c5SAndroid Build Coastguard Worker if (maxLevel <= baseLevel)
1913*8975f5c5SAndroid Build Coastguard Worker {
1914*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1915*8975f5c5SAndroid Build Coastguard Worker }
1916*8975f5c5SAndroid Build Coastguard Worker
1917*8975f5c5SAndroid Build Coastguard Worker // If any dimension is zero, this is a no-op:
1918*8975f5c5SAndroid Build Coastguard Worker //
1919*8975f5c5SAndroid Build Coastguard Worker // > Otherwise, if level_base is not defined, or if any dimension is zero, all mipmap levels are
1920*8975f5c5SAndroid Build Coastguard Worker // > left unchanged. This is not an error.
1921*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &baseImageInfo = mState.getImageDesc(mState.getBaseImageTarget(), baseLevel);
1922*8975f5c5SAndroid Build Coastguard Worker if (baseImageInfo.size.empty())
1923*8975f5c5SAndroid Build Coastguard Worker {
1924*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1925*8975f5c5SAndroid Build Coastguard Worker }
1926*8975f5c5SAndroid Build Coastguard Worker
1927*8975f5c5SAndroid Build Coastguard Worker // Clear the base image(s) immediately if needed
1928*8975f5c5SAndroid Build Coastguard Worker if (context->isRobustResourceInitEnabled())
1929*8975f5c5SAndroid Build Coastguard Worker {
1930*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator it =
1931*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator::MakeGeneric(mState.mType, baseLevel, baseLevel + 1,
1932*8975f5c5SAndroid Build Coastguard Worker ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
1933*8975f5c5SAndroid Build Coastguard Worker while (it.hasNext())
1934*8975f5c5SAndroid Build Coastguard Worker {
1935*8975f5c5SAndroid Build Coastguard Worker const ImageIndex index = it.next();
1936*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &desc = mState.getImageDesc(index.getTarget(), index.getLevelIndex());
1937*8975f5c5SAndroid Build Coastguard Worker
1938*8975f5c5SAndroid Build Coastguard Worker if (desc.initState == InitState::MayNeedInit)
1939*8975f5c5SAndroid Build Coastguard Worker {
1940*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, index));
1941*8975f5c5SAndroid Build Coastguard Worker }
1942*8975f5c5SAndroid Build Coastguard Worker }
1943*8975f5c5SAndroid Build Coastguard Worker }
1944*8975f5c5SAndroid Build Coastguard Worker
1945*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(syncState(context, Command::GenerateMipmap));
1946*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->generateMipmap(context));
1947*8975f5c5SAndroid Build Coastguard Worker
1948*8975f5c5SAndroid Build Coastguard Worker // Propagate the format and size of the base mip to the smaller ones. Cube maps are guaranteed
1949*8975f5c5SAndroid Build Coastguard Worker // to have faces of the same size and format so any faces can be picked.
1950*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
1951*8975f5c5SAndroid Build Coastguard Worker InitState::Initialized);
1952*8975f5c5SAndroid Build Coastguard Worker
1953*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
1954*8975f5c5SAndroid Build Coastguard Worker
1955*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1956*8975f5c5SAndroid Build Coastguard Worker }
1957*8975f5c5SAndroid Build Coastguard Worker
clearImage(Context * context,GLint level,GLenum format,GLenum type,const uint8_t * data)1958*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::clearImage(Context *context,
1959*8975f5c5SAndroid Build Coastguard Worker GLint level,
1960*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1961*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1962*8975f5c5SAndroid Build Coastguard Worker const uint8_t *data)
1963*8975f5c5SAndroid Build Coastguard Worker {
1964*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->clearImage(context, level, format, type, data));
1965*8975f5c5SAndroid Build Coastguard Worker
1966*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
1967*8975f5c5SAndroid Build Coastguard Worker
1968*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator it = ImageIndexIterator::MakeGeneric(
1969*8975f5c5SAndroid Build Coastguard Worker mState.mType, level, level + 1, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
1970*8975f5c5SAndroid Build Coastguard Worker while (it.hasNext())
1971*8975f5c5SAndroid Build Coastguard Worker {
1972*8975f5c5SAndroid Build Coastguard Worker const ImageIndex index = it.next();
1973*8975f5c5SAndroid Build Coastguard Worker setInitState(GL_NONE, index, InitState::Initialized);
1974*8975f5c5SAndroid Build Coastguard Worker }
1975*8975f5c5SAndroid Build Coastguard Worker
1976*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
1977*8975f5c5SAndroid Build Coastguard Worker
1978*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1979*8975f5c5SAndroid Build Coastguard Worker }
1980*8975f5c5SAndroid Build Coastguard Worker
clearSubImage(Context * context,GLint level,const Box & area,GLenum format,GLenum type,const uint8_t * data)1981*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::clearSubImage(Context *context,
1982*8975f5c5SAndroid Build Coastguard Worker GLint level,
1983*8975f5c5SAndroid Build Coastguard Worker const Box &area,
1984*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1985*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1986*8975f5c5SAndroid Build Coastguard Worker const uint8_t *data)
1987*8975f5c5SAndroid Build Coastguard Worker {
1988*8975f5c5SAndroid Build Coastguard Worker const ImageIndexIterator allImagesIterator = ImageIndexIterator::MakeGeneric(
1989*8975f5c5SAndroid Build Coastguard Worker mState.mType, level, level + 1, area.z, area.z + area.depth);
1990*8975f5c5SAndroid Build Coastguard Worker
1991*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator initImagesIterator = allImagesIterator;
1992*8975f5c5SAndroid Build Coastguard Worker while (initImagesIterator.hasNext())
1993*8975f5c5SAndroid Build Coastguard Worker {
1994*8975f5c5SAndroid Build Coastguard Worker const ImageIndex index = initImagesIterator.next();
1995*8975f5c5SAndroid Build Coastguard Worker const Box cubeFlattenedBox = index.getType() == TextureType::CubeMap
1996*8975f5c5SAndroid Build Coastguard Worker ? Box(area.x, area.y, 0, area.width, area.height, 1)
1997*8975f5c5SAndroid Build Coastguard Worker : area;
1998*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ensureSubImageInitialized(context, index, cubeFlattenedBox));
1999*8975f5c5SAndroid Build Coastguard Worker }
2000*8975f5c5SAndroid Build Coastguard Worker
2001*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->clearSubImage(context, level, area, format, type, data));
2002*8975f5c5SAndroid Build Coastguard Worker
2003*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(handleMipmapGenerationHint(context, level));
2004*8975f5c5SAndroid Build Coastguard Worker
2005*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
2006*8975f5c5SAndroid Build Coastguard Worker
2007*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2008*8975f5c5SAndroid Build Coastguard Worker }
2009*8975f5c5SAndroid Build Coastguard Worker
bindTexImageFromSurface(Context * context,egl::Surface * surface)2010*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *surface)
2011*8975f5c5SAndroid Build Coastguard Worker {
2012*8975f5c5SAndroid Build Coastguard Worker ASSERT(surface);
2013*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mBoundSurface);
2014*8975f5c5SAndroid Build Coastguard Worker mBoundSurface = surface;
2015*8975f5c5SAndroid Build Coastguard Worker
2016*8975f5c5SAndroid Build Coastguard Worker // Set the image info to the size and format of the surface
2017*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
2018*8975f5c5SAndroid Build Coastguard Worker Extents size(surface->getWidth(), surface->getHeight(), 1);
2019*8975f5c5SAndroid Build Coastguard Worker ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
2020*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc);
2021*8975f5c5SAndroid Build Coastguard Worker mState.mHasProtectedContent = surface->hasProtectedContent();
2022*8975f5c5SAndroid Build Coastguard Worker
2023*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->bindTexImage(context, surface));
2024*8975f5c5SAndroid Build Coastguard Worker
2025*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2026*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2027*8975f5c5SAndroid Build Coastguard Worker }
2028*8975f5c5SAndroid Build Coastguard Worker
releaseTexImageFromSurface(const Context * context)2029*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::releaseTexImageFromSurface(const Context *context)
2030*8975f5c5SAndroid Build Coastguard Worker {
2031*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBoundSurface);
2032*8975f5c5SAndroid Build Coastguard Worker mBoundSurface = nullptr;
2033*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->releaseTexImage(context));
2034*8975f5c5SAndroid Build Coastguard Worker
2035*8975f5c5SAndroid Build Coastguard Worker // Erase the image info for level 0
2036*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
2037*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
2038*8975f5c5SAndroid Build Coastguard Worker mState.mHasProtectedContent = false;
2039*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2040*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2041*8975f5c5SAndroid Build Coastguard Worker }
2042*8975f5c5SAndroid Build Coastguard Worker
bindStream(egl::Stream * stream)2043*8975f5c5SAndroid Build Coastguard Worker void Texture::bindStream(egl::Stream *stream)
2044*8975f5c5SAndroid Build Coastguard Worker {
2045*8975f5c5SAndroid Build Coastguard Worker ASSERT(stream);
2046*8975f5c5SAndroid Build Coastguard Worker
2047*8975f5c5SAndroid Build Coastguard Worker // It should not be possible to bind a texture already bound to another stream
2048*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBoundStream == nullptr);
2049*8975f5c5SAndroid Build Coastguard Worker
2050*8975f5c5SAndroid Build Coastguard Worker mBoundStream = stream;
2051*8975f5c5SAndroid Build Coastguard Worker
2052*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.mType == TextureType::External);
2053*8975f5c5SAndroid Build Coastguard Worker }
2054*8975f5c5SAndroid Build Coastguard Worker
releaseStream()2055*8975f5c5SAndroid Build Coastguard Worker void Texture::releaseStream()
2056*8975f5c5SAndroid Build Coastguard Worker {
2057*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBoundStream);
2058*8975f5c5SAndroid Build Coastguard Worker mBoundStream = nullptr;
2059*8975f5c5SAndroid Build Coastguard Worker }
2060*8975f5c5SAndroid Build Coastguard Worker
acquireImageFromStream(const Context * context,const egl::Stream::GLTextureDescription & desc)2061*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::acquireImageFromStream(const Context *context,
2062*8975f5c5SAndroid Build Coastguard Worker const egl::Stream::GLTextureDescription &desc)
2063*8975f5c5SAndroid Build Coastguard Worker {
2064*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBoundStream != nullptr);
2065*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, mBoundStream, desc));
2066*8975f5c5SAndroid Build Coastguard Worker
2067*8975f5c5SAndroid Build Coastguard Worker Extents size(desc.width, desc.height, 1);
2068*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0,
2069*8975f5c5SAndroid Build Coastguard Worker ImageDesc(size, Format(desc.internalFormat), InitState::Initialized));
2070*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2071*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2072*8975f5c5SAndroid Build Coastguard Worker }
2073*8975f5c5SAndroid Build Coastguard Worker
releaseImageFromStream(const Context * context)2074*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::releaseImageFromStream(const Context *context)
2075*8975f5c5SAndroid Build Coastguard Worker {
2076*8975f5c5SAndroid Build Coastguard Worker ASSERT(mBoundStream != nullptr);
2077*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, nullptr,
2078*8975f5c5SAndroid Build Coastguard Worker egl::Stream::GLTextureDescription()));
2079*8975f5c5SAndroid Build Coastguard Worker
2080*8975f5c5SAndroid Build Coastguard Worker // Set to incomplete
2081*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
2082*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2083*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2084*8975f5c5SAndroid Build Coastguard Worker }
2085*8975f5c5SAndroid Build Coastguard Worker
releaseTexImageInternal(Context * context)2086*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::releaseTexImageInternal(Context *context)
2087*8975f5c5SAndroid Build Coastguard Worker {
2088*8975f5c5SAndroid Build Coastguard Worker if (mBoundSurface)
2089*8975f5c5SAndroid Build Coastguard Worker {
2090*8975f5c5SAndroid Build Coastguard Worker // Notify the surface
2091*8975f5c5SAndroid Build Coastguard Worker egl::Error eglErr = mBoundSurface->releaseTexImageFromTexture(context);
2092*8975f5c5SAndroid Build Coastguard Worker // TODO(jmadill): Remove this once refactor is complete. http://anglebug.com/42261727
2093*8975f5c5SAndroid Build Coastguard Worker if (eglErr.isError())
2094*8975f5c5SAndroid Build Coastguard Worker {
2095*8975f5c5SAndroid Build Coastguard Worker context->handleError(GL_INVALID_OPERATION, "Error releasing tex image from texture",
2096*8975f5c5SAndroid Build Coastguard Worker __FILE__, ANGLE_FUNCTION, __LINE__);
2097*8975f5c5SAndroid Build Coastguard Worker }
2098*8975f5c5SAndroid Build Coastguard Worker
2099*8975f5c5SAndroid Build Coastguard Worker // Then, call the same method as from the surface
2100*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageFromSurface(context));
2101*8975f5c5SAndroid Build Coastguard Worker }
2102*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2103*8975f5c5SAndroid Build Coastguard Worker }
2104*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTargetImpl(Context * context,TextureType type,GLuint levels,egl::Image * imageTarget)2105*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setEGLImageTargetImpl(Context *context,
2106*8975f5c5SAndroid Build Coastguard Worker TextureType type,
2107*8975f5c5SAndroid Build Coastguard Worker GLuint levels,
2108*8975f5c5SAndroid Build Coastguard Worker egl::Image *imageTarget)
2109*8975f5c5SAndroid Build Coastguard Worker {
2110*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == mState.mType);
2111*8975f5c5SAndroid Build Coastguard Worker
2112*8975f5c5SAndroid Build Coastguard Worker // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
2113*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(releaseTexImageInternal(context));
2114*8975f5c5SAndroid Build Coastguard Worker
2115*8975f5c5SAndroid Build Coastguard Worker egl::RefCountObjectReleaser<egl::Image> releaseImage;
2116*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(orphanImages(context, &releaseImage));
2117*8975f5c5SAndroid Build Coastguard Worker
2118*8975f5c5SAndroid Build Coastguard Worker setTargetImage(context, imageTarget);
2119*8975f5c5SAndroid Build Coastguard Worker
2120*8975f5c5SAndroid Build Coastguard Worker auto initState = imageTarget->sourceInitState();
2121*8975f5c5SAndroid Build Coastguard Worker
2122*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
2123*8975f5c5SAndroid Build Coastguard Worker mState.setImageDescChain(0, levels - 1, imageTarget->getExtents(), imageTarget->getFormat(),
2124*8975f5c5SAndroid Build Coastguard Worker initState);
2125*8975f5c5SAndroid Build Coastguard Worker mState.mHasProtectedContent = imageTarget->hasProtectedContent();
2126*8975f5c5SAndroid Build Coastguard Worker
2127*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setEGLImageTarget(context, type, imageTarget));
2128*8975f5c5SAndroid Build Coastguard Worker
2129*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
2130*8975f5c5SAndroid Build Coastguard Worker
2131*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2132*8975f5c5SAndroid Build Coastguard Worker }
2133*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(Context * context,TextureType type,egl::Image * imageTarget)2134*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setEGLImageTarget(Context *context,
2135*8975f5c5SAndroid Build Coastguard Worker TextureType type,
2136*8975f5c5SAndroid Build Coastguard Worker egl::Image *imageTarget)
2137*8975f5c5SAndroid Build Coastguard Worker {
2138*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == TextureType::_2D || type == TextureType::External ||
2139*8975f5c5SAndroid Build Coastguard Worker type == TextureType::_2DArray);
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker return setEGLImageTargetImpl(context, type, 1u, imageTarget);
2142*8975f5c5SAndroid Build Coastguard Worker }
2143*8975f5c5SAndroid Build Coastguard Worker
setStorageEGLImageTarget(Context * context,TextureType type,egl::Image * imageTarget,const GLint * attrib_list)2144*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setStorageEGLImageTarget(Context *context,
2145*8975f5c5SAndroid Build Coastguard Worker TextureType type,
2146*8975f5c5SAndroid Build Coastguard Worker egl::Image *imageTarget,
2147*8975f5c5SAndroid Build Coastguard Worker const GLint *attrib_list)
2148*8975f5c5SAndroid Build Coastguard Worker {
2149*8975f5c5SAndroid Build Coastguard Worker ASSERT(type == TextureType::External || type == TextureType::_3D || type == TextureType::_2D ||
2150*8975f5c5SAndroid Build Coastguard Worker type == TextureType::_2DArray || type == TextureType::CubeMap ||
2151*8975f5c5SAndroid Build Coastguard Worker type == TextureType::CubeMapArray);
2152*8975f5c5SAndroid Build Coastguard Worker
2153*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setEGLImageTargetImpl(context, type, imageTarget->getLevelCount(), imageTarget));
2154*8975f5c5SAndroid Build Coastguard Worker
2155*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = imageTarget->getLevelCount();
2156*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
2157*8975f5c5SAndroid Build Coastguard Worker
2158*8975f5c5SAndroid Build Coastguard Worker // Changing the texture to immutable can trigger a change in the base and max levels:
2159*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0.4 section 3.8.10 pg 158:
2160*8975f5c5SAndroid Build Coastguard Worker // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
2161*8975f5c5SAndroid Build Coastguard Worker // clamped to the range[levelbase;levels].
2162*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
2163*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
2164*8975f5c5SAndroid Build Coastguard Worker
2165*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2166*8975f5c5SAndroid Build Coastguard Worker }
2167*8975f5c5SAndroid Build Coastguard Worker
getAttachmentSize(const ImageIndex & imageIndex) const2168*8975f5c5SAndroid Build Coastguard Worker Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const
2169*8975f5c5SAndroid Build Coastguard Worker {
2170*8975f5c5SAndroid Build Coastguard Worker // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
2171*8975f5c5SAndroid Build Coastguard Worker // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the
2172*8975f5c5SAndroid Build Coastguard Worker // one that belongs to the first face of the cube map.
2173*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2174*8975f5c5SAndroid Build Coastguard Worker {
2175*8975f5c5SAndroid Build Coastguard Worker // A cube map texture is cube complete if the following conditions all hold true:
2176*8975f5c5SAndroid Build Coastguard Worker // - The levelbase arrays of each of the six texture images making up the cube map have
2177*8975f5c5SAndroid Build Coastguard Worker // identical, positive, and square dimensions.
2178*8975f5c5SAndroid Build Coastguard Worker if (!mState.isCubeComplete())
2179*8975f5c5SAndroid Build Coastguard Worker {
2180*8975f5c5SAndroid Build Coastguard Worker return Extents();
2181*8975f5c5SAndroid Build Coastguard Worker }
2182*8975f5c5SAndroid Build Coastguard Worker }
2183*8975f5c5SAndroid Build Coastguard Worker
2184*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(imageIndex).size;
2185*8975f5c5SAndroid Build Coastguard Worker }
2186*8975f5c5SAndroid Build Coastguard Worker
getAttachmentFormat(GLenum,const ImageIndex & imageIndex) const2187*8975f5c5SAndroid Build Coastguard Worker Format Texture::getAttachmentFormat(GLenum /*binding*/, const ImageIndex &imageIndex) const
2188*8975f5c5SAndroid Build Coastguard Worker {
2189*8975f5c5SAndroid Build Coastguard Worker // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
2190*8975f5c5SAndroid Build Coastguard Worker // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the
2191*8975f5c5SAndroid Build Coastguard Worker // one that belongs to the first face of the cube map.
2192*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2193*8975f5c5SAndroid Build Coastguard Worker {
2194*8975f5c5SAndroid Build Coastguard Worker // A cube map texture is cube complete if the following conditions all hold true:
2195*8975f5c5SAndroid Build Coastguard Worker // - The levelbase arrays were each specified with the same effective internal format.
2196*8975f5c5SAndroid Build Coastguard Worker if (!mState.isCubeComplete())
2197*8975f5c5SAndroid Build Coastguard Worker {
2198*8975f5c5SAndroid Build Coastguard Worker return Format::Invalid();
2199*8975f5c5SAndroid Build Coastguard Worker }
2200*8975f5c5SAndroid Build Coastguard Worker }
2201*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(imageIndex).format;
2202*8975f5c5SAndroid Build Coastguard Worker }
2203*8975f5c5SAndroid Build Coastguard Worker
getAttachmentSamples(const ImageIndex & imageIndex) const2204*8975f5c5SAndroid Build Coastguard Worker GLsizei Texture::getAttachmentSamples(const ImageIndex &imageIndex) const
2205*8975f5c5SAndroid Build Coastguard Worker {
2206*8975f5c5SAndroid Build Coastguard Worker // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a
2207*8975f5c5SAndroid Build Coastguard Worker // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp).
2208*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2209*8975f5c5SAndroid Build Coastguard Worker {
2210*8975f5c5SAndroid Build Coastguard Worker return 0;
2211*8975f5c5SAndroid Build Coastguard Worker }
2212*8975f5c5SAndroid Build Coastguard Worker
2213*8975f5c5SAndroid Build Coastguard Worker return getSamples(imageIndex.getTarget(), imageIndex.getLevelIndex());
2214*8975f5c5SAndroid Build Coastguard Worker }
2215*8975f5c5SAndroid Build Coastguard Worker
isRenderable(const Context * context,GLenum binding,const ImageIndex & imageIndex) const2216*8975f5c5SAndroid Build Coastguard Worker bool Texture::isRenderable(const Context *context,
2217*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
2218*8975f5c5SAndroid Build Coastguard Worker const ImageIndex &imageIndex) const
2219*8975f5c5SAndroid Build Coastguard Worker {
2220*8975f5c5SAndroid Build Coastguard Worker if (isEGLImageTarget())
2221*8975f5c5SAndroid Build Coastguard Worker {
2222*8975f5c5SAndroid Build Coastguard Worker return ImageSibling::isRenderable(context, binding, imageIndex);
2223*8975f5c5SAndroid Build Coastguard Worker }
2224*8975f5c5SAndroid Build Coastguard Worker
2225*8975f5c5SAndroid Build Coastguard Worker // Surfaces bound to textures are always renderable. This avoids issues with surfaces with ES3+
2226*8975f5c5SAndroid Build Coastguard Worker // formats not being renderable when bound to textures in ES2 contexts.
2227*8975f5c5SAndroid Build Coastguard Worker if (mBoundSurface)
2228*8975f5c5SAndroid Build Coastguard Worker {
2229*8975f5c5SAndroid Build Coastguard Worker return true;
2230*8975f5c5SAndroid Build Coastguard Worker }
2231*8975f5c5SAndroid Build Coastguard Worker
2232*8975f5c5SAndroid Build Coastguard Worker // Skip the renderability checks if it is set via glTexParameteri and current
2233*8975f5c5SAndroid Build Coastguard Worker // context is less than GLES3. Note that we should not skip the check if the
2234*8975f5c5SAndroid Build Coastguard Worker // texture is not renderable at all. Otherwise we would end up rendering to
2235*8975f5c5SAndroid Build Coastguard Worker // textures like compressed textures that are not really renderable.
2236*8975f5c5SAndroid Build Coastguard Worker if (context->getImplementation()
2237*8975f5c5SAndroid Build Coastguard Worker ->getNativeTextureCaps()
2238*8975f5c5SAndroid Build Coastguard Worker .get(getAttachmentFormat(binding, imageIndex).info->sizedInternalFormat)
2239*8975f5c5SAndroid Build Coastguard Worker .textureAttachment &&
2240*8975f5c5SAndroid Build Coastguard Worker !mState.renderabilityValidation() && context->getClientMajorVersion() < 3)
2241*8975f5c5SAndroid Build Coastguard Worker {
2242*8975f5c5SAndroid Build Coastguard Worker return true;
2243*8975f5c5SAndroid Build Coastguard Worker }
2244*8975f5c5SAndroid Build Coastguard Worker
2245*8975f5c5SAndroid Build Coastguard Worker return getAttachmentFormat(binding, imageIndex)
2246*8975f5c5SAndroid Build Coastguard Worker .info->textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
2247*8975f5c5SAndroid Build Coastguard Worker }
2248*8975f5c5SAndroid Build Coastguard Worker
getAttachmentFixedSampleLocations(const ImageIndex & imageIndex) const2249*8975f5c5SAndroid Build Coastguard Worker bool Texture::getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const
2250*8975f5c5SAndroid Build Coastguard Worker {
2251*8975f5c5SAndroid Build Coastguard Worker // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a
2252*8975f5c5SAndroid Build Coastguard Worker // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp).
2253*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2254*8975f5c5SAndroid Build Coastguard Worker {
2255*8975f5c5SAndroid Build Coastguard Worker return true;
2256*8975f5c5SAndroid Build Coastguard Worker }
2257*8975f5c5SAndroid Build Coastguard Worker
2258*8975f5c5SAndroid Build Coastguard Worker // ES3.1 (section 9.4) requires that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS should be
2259*8975f5c5SAndroid Build Coastguard Worker // the same for all attached textures.
2260*8975f5c5SAndroid Build Coastguard Worker return getFixedSampleLocations(imageIndex.getTarget(), imageIndex.getLevelIndex());
2261*8975f5c5SAndroid Build Coastguard Worker }
2262*8975f5c5SAndroid Build Coastguard Worker
setBorderColor(const Context * context,const ColorGeneric & color)2263*8975f5c5SAndroid Build Coastguard Worker void Texture::setBorderColor(const Context *context, const ColorGeneric &color)
2264*8975f5c5SAndroid Build Coastguard Worker {
2265*8975f5c5SAndroid Build Coastguard Worker mState.mSamplerState.setBorderColor(color);
2266*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_BORDER_COLOR);
2267*8975f5c5SAndroid Build Coastguard Worker }
2268*8975f5c5SAndroid Build Coastguard Worker
getBorderColor() const2269*8975f5c5SAndroid Build Coastguard Worker const ColorGeneric &Texture::getBorderColor() const
2270*8975f5c5SAndroid Build Coastguard Worker {
2271*8975f5c5SAndroid Build Coastguard Worker return mState.mSamplerState.getBorderColor();
2272*8975f5c5SAndroid Build Coastguard Worker }
2273*8975f5c5SAndroid Build Coastguard Worker
getRequiredTextureImageUnits(const Context * context) const2274*8975f5c5SAndroid Build Coastguard Worker GLint Texture::getRequiredTextureImageUnits(const Context *context) const
2275*8975f5c5SAndroid Build Coastguard Worker {
2276*8975f5c5SAndroid Build Coastguard Worker // Only external texture types can return non-1.
2277*8975f5c5SAndroid Build Coastguard Worker if (mState.mType != TextureType::External)
2278*8975f5c5SAndroid Build Coastguard Worker {
2279*8975f5c5SAndroid Build Coastguard Worker return 1;
2280*8975f5c5SAndroid Build Coastguard Worker }
2281*8975f5c5SAndroid Build Coastguard Worker
2282*8975f5c5SAndroid Build Coastguard Worker return mTexture->getRequiredExternalTextureImageUnits(context);
2283*8975f5c5SAndroid Build Coastguard Worker }
2284*8975f5c5SAndroid Build Coastguard Worker
setCrop(const Rectangle & rect)2285*8975f5c5SAndroid Build Coastguard Worker void Texture::setCrop(const Rectangle &rect)
2286*8975f5c5SAndroid Build Coastguard Worker {
2287*8975f5c5SAndroid Build Coastguard Worker mState.setCrop(rect);
2288*8975f5c5SAndroid Build Coastguard Worker }
2289*8975f5c5SAndroid Build Coastguard Worker
getCrop() const2290*8975f5c5SAndroid Build Coastguard Worker const Rectangle &Texture::getCrop() const
2291*8975f5c5SAndroid Build Coastguard Worker {
2292*8975f5c5SAndroid Build Coastguard Worker return mState.getCrop();
2293*8975f5c5SAndroid Build Coastguard Worker }
2294*8975f5c5SAndroid Build Coastguard Worker
setGenerateMipmapHint(GLenum hint)2295*8975f5c5SAndroid Build Coastguard Worker void Texture::setGenerateMipmapHint(GLenum hint)
2296*8975f5c5SAndroid Build Coastguard Worker {
2297*8975f5c5SAndroid Build Coastguard Worker mState.setGenerateMipmapHint(hint);
2298*8975f5c5SAndroid Build Coastguard Worker }
2299*8975f5c5SAndroid Build Coastguard Worker
getGenerateMipmapHint() const2300*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getGenerateMipmapHint() const
2301*8975f5c5SAndroid Build Coastguard Worker {
2302*8975f5c5SAndroid Build Coastguard Worker return mState.getGenerateMipmapHint();
2303*8975f5c5SAndroid Build Coastguard Worker }
2304*8975f5c5SAndroid Build Coastguard Worker
setBuffer(const gl::Context * context,gl::Buffer * buffer,GLenum internalFormat)2305*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setBuffer(const gl::Context *context,
2306*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *buffer,
2307*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat)
2308*8975f5c5SAndroid Build Coastguard Worker {
2309*8975f5c5SAndroid Build Coastguard Worker // Use 0 to indicate that the size is taken from whatever size the buffer has when the texture
2310*8975f5c5SAndroid Build Coastguard Worker // buffer is used.
2311*8975f5c5SAndroid Build Coastguard Worker return setBufferRange(context, buffer, internalFormat, 0, 0);
2312*8975f5c5SAndroid Build Coastguard Worker }
2313*8975f5c5SAndroid Build Coastguard Worker
setBufferRange(const gl::Context * context,gl::Buffer * buffer,GLenum internalFormat,GLintptr offset,GLsizeiptr size)2314*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::setBufferRange(const gl::Context *context,
2315*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *buffer,
2316*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
2317*8975f5c5SAndroid Build Coastguard Worker GLintptr offset,
2318*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size)
2319*8975f5c5SAndroid Build Coastguard Worker {
2320*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableFormat = true;
2321*8975f5c5SAndroid Build Coastguard Worker mState.mBuffer.set(context, buffer, offset, size);
2322*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->setBuffer(context, internalFormat));
2323*8975f5c5SAndroid Build Coastguard Worker
2324*8975f5c5SAndroid Build Coastguard Worker mState.clearImageDescs();
2325*8975f5c5SAndroid Build Coastguard Worker if (buffer == nullptr)
2326*8975f5c5SAndroid Build Coastguard Worker {
2327*8975f5c5SAndroid Build Coastguard Worker mBufferObserver.reset();
2328*8975f5c5SAndroid Build Coastguard Worker InitState initState = DetermineInitState(context, nullptr, nullptr);
2329*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
2330*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2331*8975f5c5SAndroid Build Coastguard Worker }
2332*8975f5c5SAndroid Build Coastguard Worker
2333*8975f5c5SAndroid Build Coastguard Worker size = GetBoundBufferAvailableSize(mState.mBuffer);
2334*8975f5c5SAndroid Build Coastguard Worker
2335*8975f5c5SAndroid Build Coastguard Worker mState.mImmutableLevels = static_cast<GLuint>(1);
2336*8975f5c5SAndroid Build Coastguard Worker InternalFormat internalFormatInfo = GetSizedInternalFormatInfo(internalFormat);
2337*8975f5c5SAndroid Build Coastguard Worker Format format(internalFormat);
2338*8975f5c5SAndroid Build Coastguard Worker Extents extents(static_cast<GLuint>(size / internalFormatInfo.pixelBytes), 1, 1);
2339*8975f5c5SAndroid Build Coastguard Worker InitState initState = buffer->initState();
2340*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(TextureTarget::Buffer, 0, ImageDesc(extents, format, initState));
2341*8975f5c5SAndroid Build Coastguard Worker
2342*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(initState);
2343*8975f5c5SAndroid Build Coastguard Worker
2344*8975f5c5SAndroid Build Coastguard Worker // Observe modifications to the buffer, so that extents can be updated.
2345*8975f5c5SAndroid Build Coastguard Worker mBufferObserver.bind(buffer);
2346*8975f5c5SAndroid Build Coastguard Worker
2347*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2348*8975f5c5SAndroid Build Coastguard Worker }
2349*8975f5c5SAndroid Build Coastguard Worker
getBuffer() const2350*8975f5c5SAndroid Build Coastguard Worker const OffsetBindingPointer<Buffer> &Texture::getBuffer() const
2351*8975f5c5SAndroid Build Coastguard Worker {
2352*8975f5c5SAndroid Build Coastguard Worker return mState.mBuffer;
2353*8975f5c5SAndroid Build Coastguard Worker }
2354*8975f5c5SAndroid Build Coastguard Worker
onAttach(const Context * context,rx::UniqueSerial framebufferSerial)2355*8975f5c5SAndroid Build Coastguard Worker void Texture::onAttach(const Context *context, rx::UniqueSerial framebufferSerial)
2356*8975f5c5SAndroid Build Coastguard Worker {
2357*8975f5c5SAndroid Build Coastguard Worker addRef();
2358*8975f5c5SAndroid Build Coastguard Worker
2359*8975f5c5SAndroid Build Coastguard Worker // Duplicates allowed for multiple attachment points. See the comment in the header.
2360*8975f5c5SAndroid Build Coastguard Worker mBoundFramebufferSerials.push_back(framebufferSerial);
2361*8975f5c5SAndroid Build Coastguard Worker
2362*8975f5c5SAndroid Build Coastguard Worker if (!mState.mHasBeenBoundAsAttachment)
2363*8975f5c5SAndroid Build Coastguard Worker {
2364*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BOUND_AS_ATTACHMENT);
2365*8975f5c5SAndroid Build Coastguard Worker mState.mHasBeenBoundAsAttachment = true;
2366*8975f5c5SAndroid Build Coastguard Worker }
2367*8975f5c5SAndroid Build Coastguard Worker }
2368*8975f5c5SAndroid Build Coastguard Worker
onDetach(const Context * context,rx::UniqueSerial framebufferSerial)2369*8975f5c5SAndroid Build Coastguard Worker void Texture::onDetach(const Context *context, rx::UniqueSerial framebufferSerial)
2370*8975f5c5SAndroid Build Coastguard Worker {
2371*8975f5c5SAndroid Build Coastguard Worker // Erase first instance. If there are multiple bindings, leave the others.
2372*8975f5c5SAndroid Build Coastguard Worker ASSERT(isBoundToFramebuffer(framebufferSerial));
2373*8975f5c5SAndroid Build Coastguard Worker mBoundFramebufferSerials.remove_and_permute(framebufferSerial);
2374*8975f5c5SAndroid Build Coastguard Worker
2375*8975f5c5SAndroid Build Coastguard Worker release(context);
2376*8975f5c5SAndroid Build Coastguard Worker }
2377*8975f5c5SAndroid Build Coastguard Worker
getId() const2378*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getId() const
2379*8975f5c5SAndroid Build Coastguard Worker {
2380*8975f5c5SAndroid Build Coastguard Worker return id().value;
2381*8975f5c5SAndroid Build Coastguard Worker }
2382*8975f5c5SAndroid Build Coastguard Worker
getNativeID() const2383*8975f5c5SAndroid Build Coastguard Worker GLuint Texture::getNativeID() const
2384*8975f5c5SAndroid Build Coastguard Worker {
2385*8975f5c5SAndroid Build Coastguard Worker return mTexture->getNativeID();
2386*8975f5c5SAndroid Build Coastguard Worker }
2387*8975f5c5SAndroid Build Coastguard Worker
syncState(const Context * context,Command source)2388*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::syncState(const Context *context, Command source)
2389*8975f5c5SAndroid Build Coastguard Worker {
2390*8975f5c5SAndroid Build Coastguard Worker ASSERT(hasAnyDirtyBit() || source == Command::GenerateMipmap);
2391*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(mTexture->syncState(context, mDirtyBits, source));
2392*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.reset();
2393*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = InitState::Initialized;
2394*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2395*8975f5c5SAndroid Build Coastguard Worker }
2396*8975f5c5SAndroid Build Coastguard Worker
getAttachmentImpl() const2397*8975f5c5SAndroid Build Coastguard Worker rx::FramebufferAttachmentObjectImpl *Texture::getAttachmentImpl() const
2398*8975f5c5SAndroid Build Coastguard Worker {
2399*8975f5c5SAndroid Build Coastguard Worker return mTexture;
2400*8975f5c5SAndroid Build Coastguard Worker }
2401*8975f5c5SAndroid Build Coastguard Worker
isSamplerComplete(const Context * context,const Sampler * optionalSampler)2402*8975f5c5SAndroid Build Coastguard Worker bool Texture::isSamplerComplete(const Context *context, const Sampler *optionalSampler)
2403*8975f5c5SAndroid Build Coastguard Worker {
2404*8975f5c5SAndroid Build Coastguard Worker const auto &samplerState =
2405*8975f5c5SAndroid Build Coastguard Worker optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState;
2406*8975f5c5SAndroid Build Coastguard Worker const auto &contextState = context->getState();
2407*8975f5c5SAndroid Build Coastguard Worker
2408*8975f5c5SAndroid Build Coastguard Worker if (contextState.getContextID() != mCompletenessCache.context ||
2409*8975f5c5SAndroid Build Coastguard Worker !mCompletenessCache.samplerState.sameCompleteness(samplerState))
2410*8975f5c5SAndroid Build Coastguard Worker {
2411*8975f5c5SAndroid Build Coastguard Worker mCompletenessCache.context = context->getState().getContextID();
2412*8975f5c5SAndroid Build Coastguard Worker mCompletenessCache.samplerState = samplerState;
2413*8975f5c5SAndroid Build Coastguard Worker mCompletenessCache.samplerComplete =
2414*8975f5c5SAndroid Build Coastguard Worker mState.computeSamplerCompleteness(samplerState, contextState);
2415*8975f5c5SAndroid Build Coastguard Worker }
2416*8975f5c5SAndroid Build Coastguard Worker
2417*8975f5c5SAndroid Build Coastguard Worker return mCompletenessCache.samplerComplete;
2418*8975f5c5SAndroid Build Coastguard Worker }
2419*8975f5c5SAndroid Build Coastguard Worker
2420*8975f5c5SAndroid Build Coastguard Worker // CopyImageSubData requires that we ignore format-based completeness rules
isSamplerCompleteForCopyImage(const Context * context,const Sampler * optionalSampler) const2421*8975f5c5SAndroid Build Coastguard Worker bool Texture::isSamplerCompleteForCopyImage(const Context *context,
2422*8975f5c5SAndroid Build Coastguard Worker const Sampler *optionalSampler) const
2423*8975f5c5SAndroid Build Coastguard Worker {
2424*8975f5c5SAndroid Build Coastguard Worker const gl::SamplerState &samplerState =
2425*8975f5c5SAndroid Build Coastguard Worker optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState;
2426*8975f5c5SAndroid Build Coastguard Worker const gl::State &contextState = context->getState();
2427*8975f5c5SAndroid Build Coastguard Worker return mState.computeSamplerCompletenessForCopyImage(samplerState, contextState);
2428*8975f5c5SAndroid Build Coastguard Worker }
2429*8975f5c5SAndroid Build Coastguard Worker
SamplerCompletenessCache()2430*8975f5c5SAndroid Build Coastguard Worker Texture::SamplerCompletenessCache::SamplerCompletenessCache()
2431*8975f5c5SAndroid Build Coastguard Worker : context({0}), samplerState(), samplerComplete(false)
2432*8975f5c5SAndroid Build Coastguard Worker {}
2433*8975f5c5SAndroid Build Coastguard Worker
invalidateCompletenessCache() const2434*8975f5c5SAndroid Build Coastguard Worker void Texture::invalidateCompletenessCache() const
2435*8975f5c5SAndroid Build Coastguard Worker {
2436*8975f5c5SAndroid Build Coastguard Worker mCompletenessCache.context = {0};
2437*8975f5c5SAndroid Build Coastguard Worker }
2438*8975f5c5SAndroid Build Coastguard Worker
ensureInitialized(const Context * context)2439*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::ensureInitialized(const Context *context)
2440*8975f5c5SAndroid Build Coastguard Worker {
2441*8975f5c5SAndroid Build Coastguard Worker if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
2442*8975f5c5SAndroid Build Coastguard Worker {
2443*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2444*8975f5c5SAndroid Build Coastguard Worker }
2445*8975f5c5SAndroid Build Coastguard Worker
2446*8975f5c5SAndroid Build Coastguard Worker bool anyDirty = false;
2447*8975f5c5SAndroid Build Coastguard Worker
2448*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator it =
2449*8975f5c5SAndroid Build Coastguard Worker ImageIndexIterator::MakeGeneric(mState.mType, 0, IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1,
2450*8975f5c5SAndroid Build Coastguard Worker ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
2451*8975f5c5SAndroid Build Coastguard Worker while (it.hasNext())
2452*8975f5c5SAndroid Build Coastguard Worker {
2453*8975f5c5SAndroid Build Coastguard Worker const ImageIndex index = it.next();
2454*8975f5c5SAndroid Build Coastguard Worker ImageDesc &desc =
2455*8975f5c5SAndroid Build Coastguard Worker mState.mImageDescs[GetImageDescIndex(index.getTarget(), index.getLevelIndex())];
2456*8975f5c5SAndroid Build Coastguard Worker if (desc.initState == InitState::MayNeedInit && !desc.size.empty())
2457*8975f5c5SAndroid Build Coastguard Worker {
2458*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.mInitState == InitState::MayNeedInit);
2459*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, index));
2460*8975f5c5SAndroid Build Coastguard Worker desc.initState = InitState::Initialized;
2461*8975f5c5SAndroid Build Coastguard Worker anyDirty = true;
2462*8975f5c5SAndroid Build Coastguard Worker }
2463*8975f5c5SAndroid Build Coastguard Worker }
2464*8975f5c5SAndroid Build Coastguard Worker if (anyDirty)
2465*8975f5c5SAndroid Build Coastguard Worker {
2466*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2467*8975f5c5SAndroid Build Coastguard Worker }
2468*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = InitState::Initialized;
2469*8975f5c5SAndroid Build Coastguard Worker
2470*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2471*8975f5c5SAndroid Build Coastguard Worker }
2472*8975f5c5SAndroid Build Coastguard Worker
initState(GLenum,const ImageIndex & imageIndex) const2473*8975f5c5SAndroid Build Coastguard Worker InitState Texture::initState(GLenum /*binding*/, const ImageIndex &imageIndex) const
2474*8975f5c5SAndroid Build Coastguard Worker {
2475*8975f5c5SAndroid Build Coastguard Worker // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
2476*8975f5c5SAndroid Build Coastguard Worker // we need to check all the related ImageDescs.
2477*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2478*8975f5c5SAndroid Build Coastguard Worker {
2479*8975f5c5SAndroid Build Coastguard Worker const GLint levelIndex = imageIndex.getLevelIndex();
2480*8975f5c5SAndroid Build Coastguard Worker for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets())
2481*8975f5c5SAndroid Build Coastguard Worker {
2482*8975f5c5SAndroid Build Coastguard Worker if (mState.getImageDesc(cubeFaceTarget, levelIndex).initState == InitState::MayNeedInit)
2483*8975f5c5SAndroid Build Coastguard Worker {
2484*8975f5c5SAndroid Build Coastguard Worker return InitState::MayNeedInit;
2485*8975f5c5SAndroid Build Coastguard Worker }
2486*8975f5c5SAndroid Build Coastguard Worker }
2487*8975f5c5SAndroid Build Coastguard Worker return InitState::Initialized;
2488*8975f5c5SAndroid Build Coastguard Worker }
2489*8975f5c5SAndroid Build Coastguard Worker
2490*8975f5c5SAndroid Build Coastguard Worker return mState.getImageDesc(imageIndex).initState;
2491*8975f5c5SAndroid Build Coastguard Worker }
2492*8975f5c5SAndroid Build Coastguard Worker
setInitState(GLenum binding,const ImageIndex & imageIndex,InitState initState)2493*8975f5c5SAndroid Build Coastguard Worker void Texture::setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState)
2494*8975f5c5SAndroid Build Coastguard Worker {
2495*8975f5c5SAndroid Build Coastguard Worker // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
2496*8975f5c5SAndroid Build Coastguard Worker // we need to update all the related ImageDescs.
2497*8975f5c5SAndroid Build Coastguard Worker if (imageIndex.isEntireLevelCubeMap())
2498*8975f5c5SAndroid Build Coastguard Worker {
2499*8975f5c5SAndroid Build Coastguard Worker const GLint levelIndex = imageIndex.getLevelIndex();
2500*8975f5c5SAndroid Build Coastguard Worker for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets())
2501*8975f5c5SAndroid Build Coastguard Worker {
2502*8975f5c5SAndroid Build Coastguard Worker setInitState(binding, ImageIndex::MakeCubeMapFace(cubeFaceTarget, levelIndex),
2503*8975f5c5SAndroid Build Coastguard Worker initState);
2504*8975f5c5SAndroid Build Coastguard Worker }
2505*8975f5c5SAndroid Build Coastguard Worker }
2506*8975f5c5SAndroid Build Coastguard Worker else
2507*8975f5c5SAndroid Build Coastguard Worker {
2508*8975f5c5SAndroid Build Coastguard Worker ImageDesc newDesc = mState.getImageDesc(imageIndex);
2509*8975f5c5SAndroid Build Coastguard Worker newDesc.initState = initState;
2510*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex(), newDesc);
2511*8975f5c5SAndroid Build Coastguard Worker }
2512*8975f5c5SAndroid Build Coastguard Worker }
2513*8975f5c5SAndroid Build Coastguard Worker
setInitState(InitState initState)2514*8975f5c5SAndroid Build Coastguard Worker void Texture::setInitState(InitState initState)
2515*8975f5c5SAndroid Build Coastguard Worker {
2516*8975f5c5SAndroid Build Coastguard Worker for (ImageDesc &imageDesc : mState.mImageDescs)
2517*8975f5c5SAndroid Build Coastguard Worker {
2518*8975f5c5SAndroid Build Coastguard Worker // Only modify defined images, undefined images will remain in the initialized state
2519*8975f5c5SAndroid Build Coastguard Worker if (!imageDesc.size.empty())
2520*8975f5c5SAndroid Build Coastguard Worker {
2521*8975f5c5SAndroid Build Coastguard Worker imageDesc.initState = initState;
2522*8975f5c5SAndroid Build Coastguard Worker }
2523*8975f5c5SAndroid Build Coastguard Worker }
2524*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = initState;
2525*8975f5c5SAndroid Build Coastguard Worker }
2526*8975f5c5SAndroid Build Coastguard Worker
doesSubImageNeedInit(const Context * context,const ImageIndex & imageIndex,const Box & area) const2527*8975f5c5SAndroid Build Coastguard Worker bool Texture::doesSubImageNeedInit(const Context *context,
2528*8975f5c5SAndroid Build Coastguard Worker const ImageIndex &imageIndex,
2529*8975f5c5SAndroid Build Coastguard Worker const Box &area) const
2530*8975f5c5SAndroid Build Coastguard Worker {
2531*8975f5c5SAndroid Build Coastguard Worker if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
2532*8975f5c5SAndroid Build Coastguard Worker {
2533*8975f5c5SAndroid Build Coastguard Worker return false;
2534*8975f5c5SAndroid Build Coastguard Worker }
2535*8975f5c5SAndroid Build Coastguard Worker
2536*8975f5c5SAndroid Build Coastguard Worker // Pre-initialize the texture contents if necessary.
2537*8975f5c5SAndroid Build Coastguard Worker const ImageDesc &desc = mState.getImageDesc(imageIndex);
2538*8975f5c5SAndroid Build Coastguard Worker if (desc.initState != InitState::MayNeedInit)
2539*8975f5c5SAndroid Build Coastguard Worker {
2540*8975f5c5SAndroid Build Coastguard Worker return false;
2541*8975f5c5SAndroid Build Coastguard Worker }
2542*8975f5c5SAndroid Build Coastguard Worker
2543*8975f5c5SAndroid Build Coastguard Worker ASSERT(mState.mInitState == InitState::MayNeedInit);
2544*8975f5c5SAndroid Build Coastguard Worker return !area.coversSameExtent(desc.size);
2545*8975f5c5SAndroid Build Coastguard Worker }
2546*8975f5c5SAndroid Build Coastguard Worker
ensureSubImageInitialized(const Context * context,const ImageIndex & imageIndex,const Box & area)2547*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::ensureSubImageInitialized(const Context *context,
2548*8975f5c5SAndroid Build Coastguard Worker const ImageIndex &imageIndex,
2549*8975f5c5SAndroid Build Coastguard Worker const Box &area)
2550*8975f5c5SAndroid Build Coastguard Worker {
2551*8975f5c5SAndroid Build Coastguard Worker if (doesSubImageNeedInit(context, imageIndex, area))
2552*8975f5c5SAndroid Build Coastguard Worker {
2553*8975f5c5SAndroid Build Coastguard Worker // NOTE: do not optimize this to only initialize the passed area of the texture, or the
2554*8975f5c5SAndroid Build Coastguard Worker // initialization logic in copySubImage will be incorrect.
2555*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(initializeContents(context, GL_NONE, imageIndex));
2556*8975f5c5SAndroid Build Coastguard Worker }
2557*8975f5c5SAndroid Build Coastguard Worker // Note: binding is ignored for textures.
2558*8975f5c5SAndroid Build Coastguard Worker setInitState(GL_NONE, imageIndex, InitState::Initialized);
2559*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2560*8975f5c5SAndroid Build Coastguard Worker }
2561*8975f5c5SAndroid Build Coastguard Worker
handleMipmapGenerationHint(Context * context,int level)2562*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::handleMipmapGenerationHint(Context *context, int level)
2563*8975f5c5SAndroid Build Coastguard Worker {
2564*8975f5c5SAndroid Build Coastguard Worker if (getGenerateMipmapHint() == GL_TRUE && level == 0)
2565*8975f5c5SAndroid Build Coastguard Worker {
2566*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(generateMipmap(context));
2567*8975f5c5SAndroid Build Coastguard Worker }
2568*8975f5c5SAndroid Build Coastguard Worker
2569*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2570*8975f5c5SAndroid Build Coastguard Worker }
2571*8975f5c5SAndroid Build Coastguard Worker
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)2572*8975f5c5SAndroid Build Coastguard Worker void Texture::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
2573*8975f5c5SAndroid Build Coastguard Worker {
2574*8975f5c5SAndroid Build Coastguard Worker switch (message)
2575*8975f5c5SAndroid Build Coastguard Worker {
2576*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::ContentsChanged:
2577*8975f5c5SAndroid Build Coastguard Worker if (index != kBufferSubjectIndex)
2578*8975f5c5SAndroid Build Coastguard Worker {
2579*8975f5c5SAndroid Build Coastguard Worker // ContentsChange originates from TextureStorage11::resolveAndReleaseTexture
2580*8975f5c5SAndroid Build Coastguard Worker // which resolves the underlying multisampled texture if it exists and so
2581*8975f5c5SAndroid Build Coastguard Worker // Texture will signal dirty storage to invalidate its own cache and the
2582*8975f5c5SAndroid Build Coastguard Worker // attached framebuffer's cache.
2583*8975f5c5SAndroid Build Coastguard Worker signalDirtyStorage(InitState::Initialized);
2584*8975f5c5SAndroid Build Coastguard Worker }
2585*8975f5c5SAndroid Build Coastguard Worker break;
2586*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::DirtyBitsFlagged:
2587*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
2588*8975f5c5SAndroid Build Coastguard Worker
2589*8975f5c5SAndroid Build Coastguard Worker // Notify siblings that we are dirty.
2590*8975f5c5SAndroid Build Coastguard Worker if (index == rx::kTextureImageImplObserverMessageIndex)
2591*8975f5c5SAndroid Build Coastguard Worker {
2592*8975f5c5SAndroid Build Coastguard Worker notifySiblings(message);
2593*8975f5c5SAndroid Build Coastguard Worker }
2594*8975f5c5SAndroid Build Coastguard Worker break;
2595*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::SubjectChanged:
2596*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = InitState::MayNeedInit;
2597*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
2598*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
2599*8975f5c5SAndroid Build Coastguard Worker
2600*8975f5c5SAndroid Build Coastguard Worker // Notify siblings that we are dirty.
2601*8975f5c5SAndroid Build Coastguard Worker if (index == rx::kTextureImageImplObserverMessageIndex)
2602*8975f5c5SAndroid Build Coastguard Worker {
2603*8975f5c5SAndroid Build Coastguard Worker notifySiblings(message);
2604*8975f5c5SAndroid Build Coastguard Worker }
2605*8975f5c5SAndroid Build Coastguard Worker else if (index == kBufferSubjectIndex)
2606*8975f5c5SAndroid Build Coastguard Worker {
2607*8975f5c5SAndroid Build Coastguard Worker const gl::Buffer *buffer = mState.mBuffer.get();
2608*8975f5c5SAndroid Build Coastguard Worker ASSERT(buffer != nullptr);
2609*8975f5c5SAndroid Build Coastguard Worker
2610*8975f5c5SAndroid Build Coastguard Worker // Update cached image desc based on buffer size.
2611*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size = GetBoundBufferAvailableSize(mState.mBuffer);
2612*8975f5c5SAndroid Build Coastguard Worker
2613*8975f5c5SAndroid Build Coastguard Worker ImageDesc desc = mState.getImageDesc(TextureTarget::Buffer, 0);
2614*8975f5c5SAndroid Build Coastguard Worker const GLuint pixelBytes = desc.format.info->pixelBytes;
2615*8975f5c5SAndroid Build Coastguard Worker desc.size.width = static_cast<GLuint>(size / pixelBytes);
2616*8975f5c5SAndroid Build Coastguard Worker
2617*8975f5c5SAndroid Build Coastguard Worker mState.setImageDesc(TextureTarget::Buffer, 0, desc);
2618*8975f5c5SAndroid Build Coastguard Worker }
2619*8975f5c5SAndroid Build Coastguard Worker break;
2620*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::StorageReleased:
2621*8975f5c5SAndroid Build Coastguard Worker // When the TextureStorage is released, it needs to update the
2622*8975f5c5SAndroid Build Coastguard Worker // RenderTargetCache of the Framebuffer attaching this Texture.
2623*8975f5c5SAndroid Build Coastguard Worker // This is currently only for D3D back-end. See http://crbug.com/1234829
2624*8975f5c5SAndroid Build Coastguard Worker if (index == rx::kTextureImageImplObserverMessageIndex)
2625*8975f5c5SAndroid Build Coastguard Worker {
2626*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::StorageReleased);
2627*8975f5c5SAndroid Build Coastguard Worker }
2628*8975f5c5SAndroid Build Coastguard Worker break;
2629*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::SubjectMapped:
2630*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::SubjectUnmapped:
2631*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::BindingChanged:
2632*8975f5c5SAndroid Build Coastguard Worker {
2633*8975f5c5SAndroid Build Coastguard Worker ASSERT(index == kBufferSubjectIndex);
2634*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *buffer = mState.mBuffer.get();
2635*8975f5c5SAndroid Build Coastguard Worker ASSERT(buffer != nullptr);
2636*8975f5c5SAndroid Build Coastguard Worker if (buffer->hasContentsObserver(this))
2637*8975f5c5SAndroid Build Coastguard Worker {
2638*8975f5c5SAndroid Build Coastguard Worker onBufferContentsChange();
2639*8975f5c5SAndroid Build Coastguard Worker }
2640*8975f5c5SAndroid Build Coastguard Worker }
2641*8975f5c5SAndroid Build Coastguard Worker break;
2642*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::InitializationComplete:
2643*8975f5c5SAndroid Build Coastguard Worker ASSERT(index == rx::kTextureImageImplObserverMessageIndex);
2644*8975f5c5SAndroid Build Coastguard Worker setInitState(InitState::Initialized);
2645*8975f5c5SAndroid Build Coastguard Worker break;
2646*8975f5c5SAndroid Build Coastguard Worker case angle::SubjectMessage::InternalMemoryAllocationChanged:
2647*8975f5c5SAndroid Build Coastguard Worker // Need to mark the texture dirty to give the back end a chance to handle the new
2648*8975f5c5SAndroid Build Coastguard Worker // buffer. For example, the Vulkan back end needs to create a new buffer view that
2649*8975f5c5SAndroid Build Coastguard Worker // points to the newly allocated buffer and update the texture descriptor set.
2650*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
2651*8975f5c5SAndroid Build Coastguard Worker break;
2652*8975f5c5SAndroid Build Coastguard Worker default:
2653*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2654*8975f5c5SAndroid Build Coastguard Worker break;
2655*8975f5c5SAndroid Build Coastguard Worker }
2656*8975f5c5SAndroid Build Coastguard Worker }
2657*8975f5c5SAndroid Build Coastguard Worker
onBufferContentsChange()2658*8975f5c5SAndroid Build Coastguard Worker void Texture::onBufferContentsChange()
2659*8975f5c5SAndroid Build Coastguard Worker {
2660*8975f5c5SAndroid Build Coastguard Worker mState.mInitState = InitState::MayNeedInit;
2661*8975f5c5SAndroid Build Coastguard Worker signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
2662*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::ContentsChanged);
2663*8975f5c5SAndroid Build Coastguard Worker }
2664*8975f5c5SAndroid Build Coastguard Worker
onBindToMSRTTFramebuffer()2665*8975f5c5SAndroid Build Coastguard Worker void Texture::onBindToMSRTTFramebuffer()
2666*8975f5c5SAndroid Build Coastguard Worker {
2667*8975f5c5SAndroid Build Coastguard Worker if (!mState.mHasBeenBoundToMSRTTFramebuffer)
2668*8975f5c5SAndroid Build Coastguard Worker {
2669*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BOUND_TO_MSRTT_FRAMEBUFFER);
2670*8975f5c5SAndroid Build Coastguard Worker mState.mHasBeenBoundToMSRTTFramebuffer = true;
2671*8975f5c5SAndroid Build Coastguard Worker }
2672*8975f5c5SAndroid Build Coastguard Worker }
2673*8975f5c5SAndroid Build Coastguard Worker
getImplementationColorReadFormat(const Context * context) const2674*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getImplementationColorReadFormat(const Context *context) const
2675*8975f5c5SAndroid Build Coastguard Worker {
2676*8975f5c5SAndroid Build Coastguard Worker return mTexture->getColorReadFormat(context);
2677*8975f5c5SAndroid Build Coastguard Worker }
2678*8975f5c5SAndroid Build Coastguard Worker
getImplementationColorReadType(const Context * context) const2679*8975f5c5SAndroid Build Coastguard Worker GLenum Texture::getImplementationColorReadType(const Context *context) const
2680*8975f5c5SAndroid Build Coastguard Worker {
2681*8975f5c5SAndroid Build Coastguard Worker return mTexture->getColorReadType(context);
2682*8975f5c5SAndroid Build Coastguard Worker }
2683*8975f5c5SAndroid Build Coastguard Worker
getTexImage(const Context * context,const PixelPackState & packState,Buffer * packBuffer,TextureTarget target,GLint level,GLenum format,GLenum type,void * pixels)2684*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::getTexImage(const Context *context,
2685*8975f5c5SAndroid Build Coastguard Worker const PixelPackState &packState,
2686*8975f5c5SAndroid Build Coastguard Worker Buffer *packBuffer,
2687*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
2688*8975f5c5SAndroid Build Coastguard Worker GLint level,
2689*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2690*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2691*8975f5c5SAndroid Build Coastguard Worker void *pixels)
2692*8975f5c5SAndroid Build Coastguard Worker {
2693*8975f5c5SAndroid Build Coastguard Worker // No-op if the image level is empty.
2694*8975f5c5SAndroid Build Coastguard Worker if (getExtents(target, level).empty())
2695*8975f5c5SAndroid Build Coastguard Worker {
2696*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2697*8975f5c5SAndroid Build Coastguard Worker }
2698*8975f5c5SAndroid Build Coastguard Worker
2699*8975f5c5SAndroid Build Coastguard Worker return mTexture->getTexImage(context, packState, packBuffer, target, level, format, type,
2700*8975f5c5SAndroid Build Coastguard Worker pixels);
2701*8975f5c5SAndroid Build Coastguard Worker }
2702*8975f5c5SAndroid Build Coastguard Worker
getCompressedTexImage(const Context * context,const PixelPackState & packState,Buffer * packBuffer,TextureTarget target,GLint level,void * pixels)2703*8975f5c5SAndroid Build Coastguard Worker angle::Result Texture::getCompressedTexImage(const Context *context,
2704*8975f5c5SAndroid Build Coastguard Worker const PixelPackState &packState,
2705*8975f5c5SAndroid Build Coastguard Worker Buffer *packBuffer,
2706*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
2707*8975f5c5SAndroid Build Coastguard Worker GLint level,
2708*8975f5c5SAndroid Build Coastguard Worker void *pixels)
2709*8975f5c5SAndroid Build Coastguard Worker {
2710*8975f5c5SAndroid Build Coastguard Worker // No-op if the image level is empty.
2711*8975f5c5SAndroid Build Coastguard Worker if (getExtents(target, level).empty())
2712*8975f5c5SAndroid Build Coastguard Worker {
2713*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2714*8975f5c5SAndroid Build Coastguard Worker }
2715*8975f5c5SAndroid Build Coastguard Worker
2716*8975f5c5SAndroid Build Coastguard Worker return mTexture->getCompressedTexImage(context, packState, packBuffer, target, level, pixels);
2717*8975f5c5SAndroid Build Coastguard Worker }
2718*8975f5c5SAndroid Build Coastguard Worker
onBindAsImageTexture()2719*8975f5c5SAndroid Build Coastguard Worker void Texture::onBindAsImageTexture()
2720*8975f5c5SAndroid Build Coastguard Worker {
2721*8975f5c5SAndroid Build Coastguard Worker if (!mState.mHasBeenBoundAsImage)
2722*8975f5c5SAndroid Build Coastguard Worker {
2723*8975f5c5SAndroid Build Coastguard Worker mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE);
2724*8975f5c5SAndroid Build Coastguard Worker mState.mHasBeenBoundAsImage = true;
2725*8975f5c5SAndroid Build Coastguard Worker }
2726*8975f5c5SAndroid Build Coastguard Worker }
2727*8975f5c5SAndroid Build Coastguard Worker
2728*8975f5c5SAndroid Build Coastguard Worker } // namespace gl
2729