1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 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 // TextureGL.cpp: Implements the class methods for TextureGL.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/TextureGL.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/MemoryObject.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/angletypes.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryconversions.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/BlitGL.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/BufferGL.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ContextGL.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FramebufferGL.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FunctionsGL.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ImageGL.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/MemoryObjectGL.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/StateManagerGL.h"
29*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/SurfaceGL.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/formatutilsgl.h"
31*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/renderergl_utils.h"
32*8975f5c5SAndroid Build Coastguard Worker #include "platform/autogen/FeaturesGL_autogen.h"
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker using angle::CheckedNumeric;
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker namespace rx
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker
39*8975f5c5SAndroid Build Coastguard Worker namespace
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker // For use with the uploadTextureDataInChunks feature. See http://crbug.com/1181068
42*8975f5c5SAndroid Build Coastguard Worker constexpr const size_t kUploadTextureDataInChunksUploadSize = (120 * 1024) - 1;
43*8975f5c5SAndroid Build Coastguard Worker
GetLevelInfoIndex(gl::TextureTarget target,size_t level)44*8975f5c5SAndroid Build Coastguard Worker size_t GetLevelInfoIndex(gl::TextureTarget target, size_t level)
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker return gl::IsCubeMapFaceTarget(target)
47*8975f5c5SAndroid Build Coastguard Worker ? ((level * gl::kCubeFaceCount) + gl::CubeMapTextureTargetToFaceIndex(target))
48*8975f5c5SAndroid Build Coastguard Worker : level;
49*8975f5c5SAndroid Build Coastguard Worker }
50*8975f5c5SAndroid Build Coastguard Worker
IsLUMAFormat(GLenum format)51*8975f5c5SAndroid Build Coastguard Worker bool IsLUMAFormat(GLenum format)
52*8975f5c5SAndroid Build Coastguard Worker {
53*8975f5c5SAndroid Build Coastguard Worker return format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA;
54*8975f5c5SAndroid Build Coastguard Worker }
55*8975f5c5SAndroid Build Coastguard Worker
GetLUMAWorkaroundInfo(GLenum originalFormat,GLenum destinationFormat)56*8975f5c5SAndroid Build Coastguard Worker LUMAWorkaroundGL GetLUMAWorkaroundInfo(GLenum originalFormat, GLenum destinationFormat)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker if (IsLUMAFormat(originalFormat))
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker return LUMAWorkaroundGL(!IsLUMAFormat(destinationFormat), destinationFormat);
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker else
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker return LUMAWorkaroundGL(false, GL_NONE);
65*8975f5c5SAndroid Build Coastguard Worker }
66*8975f5c5SAndroid Build Coastguard Worker }
67*8975f5c5SAndroid Build Coastguard Worker
GetDepthStencilWorkaround(GLenum format)68*8975f5c5SAndroid Build Coastguard Worker bool GetDepthStencilWorkaround(GLenum format)
69*8975f5c5SAndroid Build Coastguard Worker {
70*8975f5c5SAndroid Build Coastguard Worker return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL;
71*8975f5c5SAndroid Build Coastguard Worker }
72*8975f5c5SAndroid Build Coastguard Worker
GetEmulatedAlphaChannel(const angle::FeaturesGL & features,const gl::InternalFormat & originalInternalFormat)73*8975f5c5SAndroid Build Coastguard Worker bool GetEmulatedAlphaChannel(const angle::FeaturesGL &features,
74*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormat)
75*8975f5c5SAndroid Build Coastguard Worker {
76*8975f5c5SAndroid Build Coastguard Worker return (features.RGBDXT1TexturesSampleZeroAlpha.enabled &&
77*8975f5c5SAndroid Build Coastguard Worker (originalInternalFormat.sizedInternalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
78*8975f5c5SAndroid Build Coastguard Worker originalInternalFormat.sizedInternalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT)) ||
79*8975f5c5SAndroid Build Coastguard Worker (features.emulateRGB10.enabled && originalInternalFormat.format == GL_RGB &&
80*8975f5c5SAndroid Build Coastguard Worker originalInternalFormat.type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT);
81*8975f5c5SAndroid Build Coastguard Worker }
82*8975f5c5SAndroid Build Coastguard Worker
GetLevelInfo(const angle::FeaturesGL & features,const gl::InternalFormat & originalInternalFormat,GLenum destinationInternalFormat)83*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL GetLevelInfo(const angle::FeaturesGL &features,
84*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormat,
85*8975f5c5SAndroid Build Coastguard Worker GLenum destinationInternalFormat)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker GLenum destinationFormat = gl::GetUnsizedFormat(destinationInternalFormat);
88*8975f5c5SAndroid Build Coastguard Worker return LevelInfoGL(originalInternalFormat.format, destinationInternalFormat,
89*8975f5c5SAndroid Build Coastguard Worker GetDepthStencilWorkaround(originalInternalFormat.format),
90*8975f5c5SAndroid Build Coastguard Worker GetLUMAWorkaroundInfo(originalInternalFormat.format, destinationFormat),
91*8975f5c5SAndroid Build Coastguard Worker GetEmulatedAlphaChannel(features, originalInternalFormat));
92*8975f5c5SAndroid Build Coastguard Worker }
93*8975f5c5SAndroid Build Coastguard Worker
GetLevelWorkaroundDirtyBits()94*8975f5c5SAndroid Build Coastguard Worker gl::Texture::DirtyBits GetLevelWorkaroundDirtyBits()
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker gl::Texture::DirtyBits bits;
97*8975f5c5SAndroid Build Coastguard Worker bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_RED);
98*8975f5c5SAndroid Build Coastguard Worker bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN);
99*8975f5c5SAndroid Build Coastguard Worker bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE);
100*8975f5c5SAndroid Build Coastguard Worker bits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA);
101*8975f5c5SAndroid Build Coastguard Worker return bits;
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker
GetMaxLevelInfoCountForTextureType(gl::TextureType type)104*8975f5c5SAndroid Build Coastguard Worker size_t GetMaxLevelInfoCountForTextureType(gl::TextureType type)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker switch (type)
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker case gl::TextureType::CubeMap:
109*8975f5c5SAndroid Build Coastguard Worker return (gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * gl::kCubeFaceCount;
110*8975f5c5SAndroid Build Coastguard Worker
111*8975f5c5SAndroid Build Coastguard Worker case gl::TextureType::External:
112*8975f5c5SAndroid Build Coastguard Worker return 1;
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker default:
115*8975f5c5SAndroid Build Coastguard Worker return gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1;
116*8975f5c5SAndroid Build Coastguard Worker }
117*8975f5c5SAndroid Build Coastguard Worker }
118*8975f5c5SAndroid Build Coastguard Worker
FormatHasBorderColorWorkarounds(GLenum format)119*8975f5c5SAndroid Build Coastguard Worker bool FormatHasBorderColorWorkarounds(GLenum format)
120*8975f5c5SAndroid Build Coastguard Worker {
121*8975f5c5SAndroid Build Coastguard Worker switch (format)
122*8975f5c5SAndroid Build Coastguard Worker {
123*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
124*8975f5c5SAndroid Build Coastguard Worker case GL_LUMINANCE_ALPHA:
125*8975f5c5SAndroid Build Coastguard Worker return true;
126*8975f5c5SAndroid Build Coastguard Worker default:
127*8975f5c5SAndroid Build Coastguard Worker return false;
128*8975f5c5SAndroid Build Coastguard Worker }
129*8975f5c5SAndroid Build Coastguard Worker }
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
132*8975f5c5SAndroid Build Coastguard Worker
LUMAWorkaroundGL()133*8975f5c5SAndroid Build Coastguard Worker LUMAWorkaroundGL::LUMAWorkaroundGL() : LUMAWorkaroundGL(false, GL_NONE) {}
134*8975f5c5SAndroid Build Coastguard Worker
LUMAWorkaroundGL(bool enabled_,GLenum workaroundFormat_)135*8975f5c5SAndroid Build Coastguard Worker LUMAWorkaroundGL::LUMAWorkaroundGL(bool enabled_, GLenum workaroundFormat_)
136*8975f5c5SAndroid Build Coastguard Worker : enabled(enabled_), workaroundFormat(workaroundFormat_)
137*8975f5c5SAndroid Build Coastguard Worker {}
138*8975f5c5SAndroid Build Coastguard Worker
LevelInfoGL()139*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL::LevelInfoGL() : LevelInfoGL(GL_NONE, GL_NONE, false, LUMAWorkaroundGL(), false) {}
140*8975f5c5SAndroid Build Coastguard Worker
LevelInfoGL(GLenum sourceFormat_,GLenum nativeInternalFormat_,bool depthStencilWorkaround_,const LUMAWorkaroundGL & lumaWorkaround_,bool emulatedAlphaChannel_)141*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL::LevelInfoGL(GLenum sourceFormat_,
142*8975f5c5SAndroid Build Coastguard Worker GLenum nativeInternalFormat_,
143*8975f5c5SAndroid Build Coastguard Worker bool depthStencilWorkaround_,
144*8975f5c5SAndroid Build Coastguard Worker const LUMAWorkaroundGL &lumaWorkaround_,
145*8975f5c5SAndroid Build Coastguard Worker bool emulatedAlphaChannel_)
146*8975f5c5SAndroid Build Coastguard Worker : sourceFormat(sourceFormat_),
147*8975f5c5SAndroid Build Coastguard Worker nativeInternalFormat(nativeInternalFormat_),
148*8975f5c5SAndroid Build Coastguard Worker depthStencilWorkaround(depthStencilWorkaround_),
149*8975f5c5SAndroid Build Coastguard Worker lumaWorkaround(lumaWorkaround_),
150*8975f5c5SAndroid Build Coastguard Worker emulatedAlphaChannel(emulatedAlphaChannel_)
151*8975f5c5SAndroid Build Coastguard Worker {}
152*8975f5c5SAndroid Build Coastguard Worker
TextureGL(const gl::TextureState & state,GLuint id)153*8975f5c5SAndroid Build Coastguard Worker TextureGL::TextureGL(const gl::TextureState &state, GLuint id)
154*8975f5c5SAndroid Build Coastguard Worker : TextureImpl(state),
155*8975f5c5SAndroid Build Coastguard Worker mAppliedSwizzle(state.getSwizzleState()),
156*8975f5c5SAndroid Build Coastguard Worker mAppliedSampler(state.getSamplerState()),
157*8975f5c5SAndroid Build Coastguard Worker mAppliedBaseLevel(state.getEffectiveBaseLevel()),
158*8975f5c5SAndroid Build Coastguard Worker mAppliedMaxLevel(state.getEffectiveMaxLevel()),
159*8975f5c5SAndroid Build Coastguard Worker mAppliedDepthStencilTextureMode(state.getDepthStencilTextureMode()),
160*8975f5c5SAndroid Build Coastguard Worker mTextureID(id)
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker mLevelInfo.resize(GetMaxLevelInfoCountForTextureType(getType()));
163*8975f5c5SAndroid Build Coastguard Worker }
164*8975f5c5SAndroid Build Coastguard Worker
~TextureGL()165*8975f5c5SAndroid Build Coastguard Worker TextureGL::~TextureGL()
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTextureID == 0);
168*8975f5c5SAndroid Build Coastguard Worker }
169*8975f5c5SAndroid Build Coastguard Worker
onDestroy(const gl::Context * context)170*8975f5c5SAndroid Build Coastguard Worker void TextureGL::onDestroy(const gl::Context *context)
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker GetImplAs<ContextGL>(context)->flushIfNecessaryBeforeDeleteTextures();
173*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
174*8975f5c5SAndroid Build Coastguard Worker stateManager->deleteTexture(mTextureID);
175*8975f5c5SAndroid Build Coastguard Worker mTextureID = 0;
176*8975f5c5SAndroid Build Coastguard Worker }
177*8975f5c5SAndroid Build Coastguard Worker
setImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)178*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setImage(const gl::Context *context,
179*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
180*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
181*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
182*8975f5c5SAndroid Build Coastguard Worker GLenum format,
183*8975f5c5SAndroid Build Coastguard Worker GLenum type,
184*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
185*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
186*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
187*8975f5c5SAndroid Build Coastguard Worker {
188*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
189*8975f5c5SAndroid Build Coastguard Worker
190*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
191*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
192*8975f5c5SAndroid Build Coastguard Worker
193*8975f5c5SAndroid Build Coastguard Worker if (features.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer &&
194*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength != 0 && unpack.rowLength < size.width)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker // The rows overlap in unpack memory. Upload the texture row by row to work around
197*8975f5c5SAndroid Build Coastguard Worker // driver bug.
198*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(
199*8975f5c5SAndroid Build Coastguard Worker reserveTexImageToBeFilled(context, target, level, internalFormat, size, format, type));
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker if (size.width == 0 || size.height == 0 || size.depth == 0)
202*8975f5c5SAndroid Build Coastguard Worker {
203*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker gl::Box area(0, 0, 0, size.width, size.height, size.depth);
207*8975f5c5SAndroid Build Coastguard Worker return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
208*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, 0, pixels);
209*8975f5c5SAndroid Build Coastguard Worker }
210*8975f5c5SAndroid Build Coastguard Worker
211*8975f5c5SAndroid Build Coastguard Worker if (features.unpackLastRowSeparatelyForPaddingInclusion.enabled)
212*8975f5c5SAndroid Build Coastguard Worker {
213*8975f5c5SAndroid Build Coastguard Worker bool apply = false;
214*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ShouldApplyLastRowPaddingWorkaround(
215*8975f5c5SAndroid Build Coastguard Worker GetImplAs<ContextGL>(context), size, unpack, unpackBuffer, format, type,
216*8975f5c5SAndroid Build Coastguard Worker nativegl::UseTexImage3D(getType()), pixels, &apply));
217*8975f5c5SAndroid Build Coastguard Worker
218*8975f5c5SAndroid Build Coastguard Worker // The driver will think the pixel buffer doesn't have enough data, work around this bug
219*8975f5c5SAndroid Build Coastguard Worker // by uploading the last row (and last level if 3D) separately.
220*8975f5c5SAndroid Build Coastguard Worker if (apply)
221*8975f5c5SAndroid Build Coastguard Worker {
222*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(reserveTexImageToBeFilled(context, target, level, internalFormat, size,
223*8975f5c5SAndroid Build Coastguard Worker format, type));
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker if (size.width == 0 || size.height == 0 || size.depth == 0)
226*8975f5c5SAndroid Build Coastguard Worker {
227*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
228*8975f5c5SAndroid Build Coastguard Worker }
229*8975f5c5SAndroid Build Coastguard Worker
230*8975f5c5SAndroid Build Coastguard Worker gl::Box area(0, 0, 0, size.width, size.height, size.depth);
231*8975f5c5SAndroid Build Coastguard Worker return setSubImagePaddingWorkaround(context, target, level, area, format, type, unpack,
232*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, pixels);
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker
236*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setImageHelper(context, target, level, internalFormat, size, format, type, pixels));
237*8975f5c5SAndroid Build Coastguard Worker
238*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker
setImageHelper(const gl::Context * context,gl::TextureTarget target,size_t level,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type,const uint8_t * pixels)241*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setImageHelper(const gl::Context *context,
242*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
243*8975f5c5SAndroid Build Coastguard Worker size_t level,
244*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
245*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
246*8975f5c5SAndroid Build Coastguard Worker GLenum format,
247*8975f5c5SAndroid Build Coastguard Worker GLenum type,
248*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
249*8975f5c5SAndroid Build Coastguard Worker {
250*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == getType());
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
253*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
254*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
255*8975f5c5SAndroid Build Coastguard Worker
256*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
257*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, type);
258*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat =
259*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexImageFormat(functions, features, internalFormat, format, type);
260*8975f5c5SAndroid Build Coastguard Worker
261*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
262*8975f5c5SAndroid Build Coastguard Worker
263*8975f5c5SAndroid Build Coastguard Worker if (features.resetTexImage2DBaseLevel.enabled)
264*8975f5c5SAndroid Build Coastguard Worker {
265*8975f5c5SAndroid Build Coastguard Worker // setBaseLevel doesn't ever generate errors.
266*8975f5c5SAndroid Build Coastguard Worker (void)setBaseLevel(context, 0);
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker
269*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
272*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
273*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage2D(nativegl::GetTextureBindingTarget(target),
274*8975f5c5SAndroid Build Coastguard Worker static_cast<GLint>(level), texImageFormat.internalFormat,
275*8975f5c5SAndroid Build Coastguard Worker size.width, size.height, 0, texImageFormat.format,
276*8975f5c5SAndroid Build Coastguard Worker texImageFormat.type, pixels));
277*8975f5c5SAndroid Build Coastguard Worker }
278*8975f5c5SAndroid Build Coastguard Worker else
279*8975f5c5SAndroid Build Coastguard Worker {
280*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
281*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
282*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage3D(ToGLenum(target), static_cast<GLint>(level),
283*8975f5c5SAndroid Build Coastguard Worker texImageFormat.internalFormat, size.width, size.height,
284*8975f5c5SAndroid Build Coastguard Worker size.depth, 0, texImageFormat.format,
285*8975f5c5SAndroid Build Coastguard Worker texImageFormat.type, pixels));
286*8975f5c5SAndroid Build Coastguard Worker }
287*8975f5c5SAndroid Build Coastguard Worker
288*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL levelInfo =
289*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texImageFormat.internalFormat);
290*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, level, 1, levelInfo);
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker if (features.setZeroLevelBeforeGenerateMipmap.enabled && getType() == gl::TextureType::_2D &&
293*8975f5c5SAndroid Build Coastguard Worker level != 0 && mLevelInfo[0].nativeInternalFormat == GL_NONE)
294*8975f5c5SAndroid Build Coastguard Worker {
295*8975f5c5SAndroid Build Coastguard Worker // Only fill level zero if it's possible that mipmaps can be generated with this format
296*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
297*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, type);
298*8975f5c5SAndroid Build Coastguard Worker if (!internalFormatInfo.sized ||
299*8975f5c5SAndroid Build Coastguard Worker (internalFormatInfo.filterSupport(context->getClientVersion(),
300*8975f5c5SAndroid Build Coastguard Worker context->getExtensions()) &&
301*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.textureAttachmentSupport(context->getClientVersion(),
302*8975f5c5SAndroid Build Coastguard Worker context->getExtensions())))
303*8975f5c5SAndroid Build Coastguard Worker {
304*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
305*8975f5c5SAndroid Build Coastguard Worker context,
306*8975f5c5SAndroid Build Coastguard Worker functions->texImage2D(nativegl::GetTextureBindingTarget(target), 0,
307*8975f5c5SAndroid Build Coastguard Worker texImageFormat.internalFormat, 1, 1, 0, texImageFormat.format,
308*8975f5c5SAndroid Build Coastguard Worker texImageFormat.type, nullptr));
309*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, 0, 1, levelInfo);
310*8975f5c5SAndroid Build Coastguard Worker }
311*8975f5c5SAndroid Build Coastguard Worker }
312*8975f5c5SAndroid Build Coastguard Worker
313*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
314*8975f5c5SAndroid Build Coastguard Worker }
315*8975f5c5SAndroid Build Coastguard Worker
reserveTexImageToBeFilled(const gl::Context * context,gl::TextureTarget target,size_t level,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type)316*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::reserveTexImageToBeFilled(const gl::Context *context,
317*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
318*8975f5c5SAndroid Build Coastguard Worker size_t level,
319*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
320*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
321*8975f5c5SAndroid Build Coastguard Worker GLenum format,
322*8975f5c5SAndroid Build Coastguard Worker GLenum type)
323*8975f5c5SAndroid Build Coastguard Worker {
324*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
325*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackBuffer(context, nullptr));
326*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setImageHelper(context, target, level, internalFormat, size, format, type, nullptr));
327*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
328*8975f5c5SAndroid Build Coastguard Worker }
329*8975f5c5SAndroid Build Coastguard Worker
setSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,gl::Buffer * unpackBuffer,const uint8_t * pixels)330*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setSubImage(const gl::Context *context,
331*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
332*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
333*8975f5c5SAndroid Build Coastguard Worker GLenum format,
334*8975f5c5SAndroid Build Coastguard Worker GLenum type,
335*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
336*8975f5c5SAndroid Build Coastguard Worker gl::Buffer *unpackBuffer,
337*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
338*8975f5c5SAndroid Build Coastguard Worker {
339*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(index.getTarget()) == getType());
340*8975f5c5SAndroid Build Coastguard Worker
341*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
342*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
343*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
344*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
345*8975f5c5SAndroid Build Coastguard Worker
346*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo = *mState.getImageDesc(index).format.info;
347*8975f5c5SAndroid Build Coastguard Worker nativegl::TexSubImageFormat texSubImageFormat =
348*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexSubImageFormat(functions, features, format, type);
349*8975f5c5SAndroid Build Coastguard Worker
350*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
351*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
352*8975f5c5SAndroid Build Coastguard Worker
353*8975f5c5SAndroid Build Coastguard Worker ASSERT(getLevelInfo(target, level).lumaWorkaround.enabled ==
354*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texSubImageFormat.format)
355*8975f5c5SAndroid Build Coastguard Worker .lumaWorkaround.enabled);
356*8975f5c5SAndroid Build Coastguard Worker
357*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
358*8975f5c5SAndroid Build Coastguard Worker if (features.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer &&
359*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength != 0 && unpack.rowLength < area.width)
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
362*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, 0, pixels));
363*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
364*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
365*8975f5c5SAndroid Build Coastguard Worker }
366*8975f5c5SAndroid Build Coastguard Worker
367*8975f5c5SAndroid Build Coastguard Worker if (features.unpackLastRowSeparatelyForPaddingInclusion.enabled)
368*8975f5c5SAndroid Build Coastguard Worker {
369*8975f5c5SAndroid Build Coastguard Worker gl::Extents size(area.width, area.height, area.depth);
370*8975f5c5SAndroid Build Coastguard Worker
371*8975f5c5SAndroid Build Coastguard Worker bool apply = false;
372*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(ShouldApplyLastRowPaddingWorkaround(
373*8975f5c5SAndroid Build Coastguard Worker GetImplAs<ContextGL>(context), size, unpack, unpackBuffer, format, type,
374*8975f5c5SAndroid Build Coastguard Worker nativegl::UseTexImage3D(getType()), pixels, &apply));
375*8975f5c5SAndroid Build Coastguard Worker
376*8975f5c5SAndroid Build Coastguard Worker // The driver will think the pixel buffer doesn't have enough data, work around this bug
377*8975f5c5SAndroid Build Coastguard Worker // by uploading the last row (and last level if 3D) separately.
378*8975f5c5SAndroid Build Coastguard Worker if (apply)
379*8975f5c5SAndroid Build Coastguard Worker {
380*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setSubImagePaddingWorkaround(context, target, level, area, format, type,
381*8975f5c5SAndroid Build Coastguard Worker unpack, unpackBuffer, pixels));
382*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
383*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
384*8975f5c5SAndroid Build Coastguard Worker }
385*8975f5c5SAndroid Build Coastguard Worker }
386*8975f5c5SAndroid Build Coastguard Worker
387*8975f5c5SAndroid Build Coastguard Worker if (features.uploadTextureDataInChunks.enabled)
388*8975f5c5SAndroid Build Coastguard Worker {
389*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
390*8975f5c5SAndroid Build Coastguard Worker unpackBuffer, kUploadTextureDataInChunksUploadSize,
391*8975f5c5SAndroid Build Coastguard Worker pixels));
392*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
393*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
394*8975f5c5SAndroid Build Coastguard Worker }
395*8975f5c5SAndroid Build Coastguard Worker
396*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
397*8975f5c5SAndroid Build Coastguard Worker {
398*8975f5c5SAndroid Build Coastguard Worker ASSERT(area.z == 0 && area.depth == 1);
399*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
400*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage2D(nativegl::GetTextureBindingTarget(target),
401*8975f5c5SAndroid Build Coastguard Worker static_cast<GLint>(level), area.x, area.y, area.width,
402*8975f5c5SAndroid Build Coastguard Worker area.height, texSubImageFormat.format,
403*8975f5c5SAndroid Build Coastguard Worker texSubImageFormat.type, pixels));
404*8975f5c5SAndroid Build Coastguard Worker }
405*8975f5c5SAndroid Build Coastguard Worker else
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
408*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texSubImage3D(
409*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
410*8975f5c5SAndroid Build Coastguard Worker area.z, area.width, area.height, area.depth,
411*8975f5c5SAndroid Build Coastguard Worker texSubImageFormat.format, texSubImageFormat.type, pixels));
412*8975f5c5SAndroid Build Coastguard Worker }
413*8975f5c5SAndroid Build Coastguard Worker
414*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
415*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
416*8975f5c5SAndroid Build Coastguard Worker }
417*8975f5c5SAndroid Build Coastguard Worker
setSubImageRowByRowWorkaround(const gl::Context * context,gl::TextureTarget target,size_t level,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,const gl::Buffer * unpackBuffer,size_t maxBytesUploadedPerChunk,const uint8_t * pixels)418*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setSubImageRowByRowWorkaround(const gl::Context *context,
419*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
420*8975f5c5SAndroid Build Coastguard Worker size_t level,
421*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
422*8975f5c5SAndroid Build Coastguard Worker GLenum format,
423*8975f5c5SAndroid Build Coastguard Worker GLenum type,
424*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
425*8975f5c5SAndroid Build Coastguard Worker const gl::Buffer *unpackBuffer,
426*8975f5c5SAndroid Build Coastguard Worker size_t maxBytesUploadedPerChunk,
427*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
428*8975f5c5SAndroid Build Coastguard Worker {
429*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
430*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
431*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
432*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
433*8975f5c5SAndroid Build Coastguard Worker
434*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState directUnpack = unpack;
435*8975f5c5SAndroid Build Coastguard Worker directUnpack.skipRows = 0;
436*8975f5c5SAndroid Build Coastguard Worker directUnpack.skipPixels = 0;
437*8975f5c5SAndroid Build Coastguard Worker directUnpack.skipImages = 0;
438*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, directUnpack));
439*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackBuffer(context, unpackBuffer));
440*8975f5c5SAndroid Build Coastguard Worker
441*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
442*8975f5c5SAndroid Build Coastguard Worker GLuint rowBytes = 0;
443*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, area.width, unpack.alignment,
444*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength, &rowBytes));
445*8975f5c5SAndroid Build Coastguard Worker GLuint imageBytes = 0;
446*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeDepthPitch(area.height, unpack.imageHeight,
447*8975f5c5SAndroid Build Coastguard Worker rowBytes, &imageBytes));
448*8975f5c5SAndroid Build Coastguard Worker
449*8975f5c5SAndroid Build Coastguard Worker bool useTexImage3D = nativegl::UseTexImage3D(getType());
450*8975f5c5SAndroid Build Coastguard Worker GLuint skipBytes = 0;
451*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeSkipBytes(type, rowBytes, imageBytes, unpack,
452*8975f5c5SAndroid Build Coastguard Worker useTexImage3D, &skipBytes));
453*8975f5c5SAndroid Build Coastguard Worker
454*8975f5c5SAndroid Build Coastguard Worker GLint rowsPerChunk =
455*8975f5c5SAndroid Build Coastguard Worker std::min(std::max(static_cast<GLint>(maxBytesUploadedPerChunk / rowBytes), 1), area.height);
456*8975f5c5SAndroid Build Coastguard Worker if (maxBytesUploadedPerChunk > 0 && rowsPerChunk < area.height)
457*8975f5c5SAndroid Build Coastguard Worker {
458*8975f5c5SAndroid Build Coastguard Worker ANGLE_PERF_WARNING(contextGL->getDebug(), GL_DEBUG_SEVERITY_LOW,
459*8975f5c5SAndroid Build Coastguard Worker "Chunking upload of texture data to work around driver hangs.");
460*8975f5c5SAndroid Build Coastguard Worker }
461*8975f5c5SAndroid Build Coastguard Worker
462*8975f5c5SAndroid Build Coastguard Worker nativegl::TexSubImageFormat texSubImageFormat =
463*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexSubImageFormat(functions, features, format, type);
464*8975f5c5SAndroid Build Coastguard Worker
465*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixelsWithSkip = pixels + skipBytes;
466*8975f5c5SAndroid Build Coastguard Worker if (useTexImage3D)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker for (GLint image = 0; image < area.depth; ++image)
469*8975f5c5SAndroid Build Coastguard Worker {
470*8975f5c5SAndroid Build Coastguard Worker GLint imageByteOffset = image * imageBytes;
471*8975f5c5SAndroid Build Coastguard Worker for (GLint row = 0; row < area.height; row += rowsPerChunk)
472*8975f5c5SAndroid Build Coastguard Worker {
473*8975f5c5SAndroid Build Coastguard Worker GLint height = std::min(rowsPerChunk, area.height - row);
474*8975f5c5SAndroid Build Coastguard Worker GLint byteOffset = imageByteOffset + row * rowBytes;
475*8975f5c5SAndroid Build Coastguard Worker const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
476*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
477*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage3D(
478*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, row + area.y,
479*8975f5c5SAndroid Build Coastguard Worker image + area.z, area.width, height, 1, texSubImageFormat.format,
480*8975f5c5SAndroid Build Coastguard Worker texSubImageFormat.type, rowPixels));
481*8975f5c5SAndroid Build Coastguard Worker }
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker }
484*8975f5c5SAndroid Build Coastguard Worker else
485*8975f5c5SAndroid Build Coastguard Worker {
486*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage2D(getType()));
487*8975f5c5SAndroid Build Coastguard Worker for (GLint row = 0; row < area.height; row += rowsPerChunk)
488*8975f5c5SAndroid Build Coastguard Worker {
489*8975f5c5SAndroid Build Coastguard Worker GLint height = std::min(rowsPerChunk, area.height - row);
490*8975f5c5SAndroid Build Coastguard Worker GLint byteOffset = row * rowBytes;
491*8975f5c5SAndroid Build Coastguard Worker const GLubyte *rowPixels = pixelsWithSkip + byteOffset;
492*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texSubImage2D(
493*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x,
494*8975f5c5SAndroid Build Coastguard Worker row + area.y, area.width, height, texSubImageFormat.format,
495*8975f5c5SAndroid Build Coastguard Worker texSubImageFormat.type, rowPixels));
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker }
498*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
499*8975f5c5SAndroid Build Coastguard Worker }
500*8975f5c5SAndroid Build Coastguard Worker
setSubImagePaddingWorkaround(const gl::Context * context,gl::TextureTarget target,size_t level,const gl::Box & area,GLenum format,GLenum type,const gl::PixelUnpackState & unpack,const gl::Buffer * unpackBuffer,const uint8_t * pixels)501*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setSubImagePaddingWorkaround(const gl::Context *context,
502*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
503*8975f5c5SAndroid Build Coastguard Worker size_t level,
504*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
505*8975f5c5SAndroid Build Coastguard Worker GLenum format,
506*8975f5c5SAndroid Build Coastguard Worker GLenum type,
507*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
508*8975f5c5SAndroid Build Coastguard Worker const gl::Buffer *unpackBuffer,
509*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
510*8975f5c5SAndroid Build Coastguard Worker {
511*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
512*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
513*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
514*8975f5c5SAndroid Build Coastguard Worker
515*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
516*8975f5c5SAndroid Build Coastguard Worker GLuint rowBytes = 0;
517*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, area.width, unpack.alignment,
518*8975f5c5SAndroid Build Coastguard Worker unpack.rowLength, &rowBytes));
519*8975f5c5SAndroid Build Coastguard Worker GLuint imageBytes = 0;
520*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeDepthPitch(area.height, unpack.imageHeight,
521*8975f5c5SAndroid Build Coastguard Worker rowBytes, &imageBytes));
522*8975f5c5SAndroid Build Coastguard Worker bool useTexImage3D = nativegl::UseTexImage3D(getType());
523*8975f5c5SAndroid Build Coastguard Worker GLuint skipBytes = 0;
524*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeSkipBytes(type, rowBytes, imageBytes, unpack,
525*8975f5c5SAndroid Build Coastguard Worker useTexImage3D, &skipBytes));
526*8975f5c5SAndroid Build Coastguard Worker
527*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, unpack));
528*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackBuffer(context, unpackBuffer));
529*8975f5c5SAndroid Build Coastguard Worker
530*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState directUnpack;
531*8975f5c5SAndroid Build Coastguard Worker directUnpack.alignment = 1;
532*8975f5c5SAndroid Build Coastguard Worker
533*8975f5c5SAndroid Build Coastguard Worker if (useTexImage3D)
534*8975f5c5SAndroid Build Coastguard Worker {
535*8975f5c5SAndroid Build Coastguard Worker // Upload all but the last slice
536*8975f5c5SAndroid Build Coastguard Worker if (area.depth > 1)
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
539*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level),
540*8975f5c5SAndroid Build Coastguard Worker area.x, area.y, area.z, area.width, area.height,
541*8975f5c5SAndroid Build Coastguard Worker area.depth - 1, format, type, pixels));
542*8975f5c5SAndroid Build Coastguard Worker }
543*8975f5c5SAndroid Build Coastguard Worker
544*8975f5c5SAndroid Build Coastguard Worker // Upload the last slice but its last row
545*8975f5c5SAndroid Build Coastguard Worker if (area.height > 1)
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker // Do not include skipBytes in the last image pixel start offset as it will be done by
548*8975f5c5SAndroid Build Coastguard Worker // the driver
549*8975f5c5SAndroid Build Coastguard Worker GLint lastImageOffset = (area.depth - 1) * imageBytes;
550*8975f5c5SAndroid Build Coastguard Worker const GLubyte *lastImagePixels = pixels + lastImageOffset;
551*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texSubImage3D(
552*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
553*8975f5c5SAndroid Build Coastguard Worker area.z + area.depth - 1, area.width, area.height - 1, 1,
554*8975f5c5SAndroid Build Coastguard Worker format, type, lastImagePixels));
555*8975f5c5SAndroid Build Coastguard Worker }
556*8975f5c5SAndroid Build Coastguard Worker
557*8975f5c5SAndroid Build Coastguard Worker // Upload the last row of the last slice "manually"
558*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, directUnpack));
559*8975f5c5SAndroid Build Coastguard Worker
560*8975f5c5SAndroid Build Coastguard Worker GLint lastRowOffset =
561*8975f5c5SAndroid Build Coastguard Worker skipBytes + (area.depth - 1) * imageBytes + (area.height - 1) * rowBytes;
562*8975f5c5SAndroid Build Coastguard Worker const GLubyte *lastRowPixels = pixels + lastRowOffset;
563*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
564*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage3D(ToGLenum(target), static_cast<GLint>(level), area.x,
565*8975f5c5SAndroid Build Coastguard Worker area.y + area.height - 1, area.z + area.depth - 1,
566*8975f5c5SAndroid Build Coastguard Worker area.width, 1, 1, format, type, lastRowPixels));
567*8975f5c5SAndroid Build Coastguard Worker }
568*8975f5c5SAndroid Build Coastguard Worker else
569*8975f5c5SAndroid Build Coastguard Worker {
570*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage2D(getType()));
571*8975f5c5SAndroid Build Coastguard Worker
572*8975f5c5SAndroid Build Coastguard Worker // Upload all but the last row
573*8975f5c5SAndroid Build Coastguard Worker if (area.height > 1)
574*8975f5c5SAndroid Build Coastguard Worker {
575*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texSubImage2D(
576*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
577*8975f5c5SAndroid Build Coastguard Worker area.width, area.height - 1, format, type, pixels));
578*8975f5c5SAndroid Build Coastguard Worker }
579*8975f5c5SAndroid Build Coastguard Worker
580*8975f5c5SAndroid Build Coastguard Worker // Upload the last row "manually"
581*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, directUnpack));
582*8975f5c5SAndroid Build Coastguard Worker
583*8975f5c5SAndroid Build Coastguard Worker GLint lastRowOffset = skipBytes + (area.height - 1) * rowBytes;
584*8975f5c5SAndroid Build Coastguard Worker const GLubyte *lastRowPixels = pixels + lastRowOffset;
585*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texSubImage2D(ToGLenum(target), static_cast<GLint>(level),
586*8975f5c5SAndroid Build Coastguard Worker area.x, area.y + area.height - 1, area.width,
587*8975f5c5SAndroid Build Coastguard Worker 1, format, type, lastRowPixels));
588*8975f5c5SAndroid Build Coastguard Worker }
589*8975f5c5SAndroid Build Coastguard Worker
590*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
591*8975f5c5SAndroid Build Coastguard Worker }
592*8975f5c5SAndroid Build Coastguard Worker
setCompressedImage(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)593*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setCompressedImage(const gl::Context *context,
594*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
595*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
596*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
597*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
598*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
599*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
600*8975f5c5SAndroid Build Coastguard Worker {
601*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
602*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
603*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
604*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
605*8975f5c5SAndroid Build Coastguard Worker
606*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
607*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
608*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == getType());
609*8975f5c5SAndroid Build Coastguard Worker
610*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
611*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalFormat);
612*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexImageFormat compressedTexImageFormat =
613*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedTexImageFormat(functions, features, internalFormat);
614*8975f5c5SAndroid Build Coastguard Worker
615*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
616*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, unpack));
617*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
618*8975f5c5SAndroid Build Coastguard Worker {
619*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
620*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
621*8975f5c5SAndroid Build Coastguard Worker context, functions->compressedTexImage2D(ToGLenum(target), static_cast<GLint>(level),
622*8975f5c5SAndroid Build Coastguard Worker compressedTexImageFormat.internalFormat,
623*8975f5c5SAndroid Build Coastguard Worker size.width, size.height, 0,
624*8975f5c5SAndroid Build Coastguard Worker static_cast<GLsizei>(imageSize), pixels));
625*8975f5c5SAndroid Build Coastguard Worker }
626*8975f5c5SAndroid Build Coastguard Worker else
627*8975f5c5SAndroid Build Coastguard Worker {
628*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
629*8975f5c5SAndroid Build Coastguard Worker
630*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
631*8975f5c5SAndroid Build Coastguard Worker context, functions->compressedTexImage3D(ToGLenum(target), static_cast<GLint>(level),
632*8975f5c5SAndroid Build Coastguard Worker compressedTexImageFormat.internalFormat,
633*8975f5c5SAndroid Build Coastguard Worker size.width, size.height, size.depth, 0,
634*8975f5c5SAndroid Build Coastguard Worker static_cast<GLsizei>(imageSize), pixels));
635*8975f5c5SAndroid Build Coastguard Worker }
636*8975f5c5SAndroid Build Coastguard Worker
637*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL levelInfo =
638*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, compressedTexImageFormat.internalFormat);
639*8975f5c5SAndroid Build Coastguard Worker ASSERT(!levelInfo.lumaWorkaround.enabled);
640*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, level, 1, levelInfo);
641*8975f5c5SAndroid Build Coastguard Worker
642*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
643*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
644*8975f5c5SAndroid Build Coastguard Worker }
645*8975f5c5SAndroid Build Coastguard Worker
setCompressedSubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Box & area,GLenum format,const gl::PixelUnpackState & unpack,size_t imageSize,const uint8_t * pixels)646*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setCompressedSubImage(const gl::Context *context,
647*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
648*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
649*8975f5c5SAndroid Build Coastguard Worker GLenum format,
650*8975f5c5SAndroid Build Coastguard Worker const gl::PixelUnpackState &unpack,
651*8975f5c5SAndroid Build Coastguard Worker size_t imageSize,
652*8975f5c5SAndroid Build Coastguard Worker const uint8_t *pixels)
653*8975f5c5SAndroid Build Coastguard Worker {
654*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
655*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
656*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
657*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
658*8975f5c5SAndroid Build Coastguard Worker
659*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
660*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
661*8975f5c5SAndroid Build Coastguard Worker ASSERT(TextureTargetToType(target) == getType());
662*8975f5c5SAndroid Build Coastguard Worker
663*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo = gl::GetSizedInternalFormatInfo(format);
664*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
665*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedSubTexImageFormat(functions, features, format);
666*8975f5c5SAndroid Build Coastguard Worker
667*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
668*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, unpack));
669*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
670*8975f5c5SAndroid Build Coastguard Worker {
671*8975f5c5SAndroid Build Coastguard Worker ASSERT(area.z == 0 && area.depth == 1);
672*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->compressedTexSubImage2D(
673*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, area.y,
674*8975f5c5SAndroid Build Coastguard Worker area.width, area.height, compressedTexSubImageFormat.format,
675*8975f5c5SAndroid Build Coastguard Worker static_cast<GLsizei>(imageSize), pixels));
676*8975f5c5SAndroid Build Coastguard Worker }
677*8975f5c5SAndroid Build Coastguard Worker else
678*8975f5c5SAndroid Build Coastguard Worker {
679*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
680*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
681*8975f5c5SAndroid Build Coastguard Worker functions->compressedTexSubImage3D(
682*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), area.x, area.y, area.z,
683*8975f5c5SAndroid Build Coastguard Worker area.width, area.height, area.depth, compressedTexSubImageFormat.format,
684*8975f5c5SAndroid Build Coastguard Worker static_cast<GLsizei>(imageSize), pixels));
685*8975f5c5SAndroid Build Coastguard Worker }
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker ASSERT(!getLevelInfo(target, level).lumaWorkaround.enabled &&
688*8975f5c5SAndroid Build Coastguard Worker !GetLevelInfo(features, originalInternalFormatInfo, compressedTexSubImageFormat.format)
689*8975f5c5SAndroid Build Coastguard Worker .lumaWorkaround.enabled);
690*8975f5c5SAndroid Build Coastguard Worker
691*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
692*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
693*8975f5c5SAndroid Build Coastguard Worker }
694*8975f5c5SAndroid Build Coastguard Worker
copyImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Rectangle & sourceArea,GLenum internalFormat,gl::Framebuffer * source)695*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::copyImage(const gl::Context *context,
696*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
697*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
698*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
699*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
700*8975f5c5SAndroid Build Coastguard Worker {
701*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
702*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
703*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
704*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
705*8975f5c5SAndroid Build Coastguard Worker
706*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
707*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
708*8975f5c5SAndroid Build Coastguard Worker GLenum type = source->getImplementationColorReadType(context);
709*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
710*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, type);
711*8975f5c5SAndroid Build Coastguard Worker nativegl::CopyTexImageImageFormat copyTexImageFormat =
712*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCopyTexImageImageFormat(functions, features, internalFormat, type);
713*8975f5c5SAndroid Build Coastguard Worker
714*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
715*8975f5c5SAndroid Build Coastguard Worker
716*8975f5c5SAndroid Build Coastguard Worker const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
717*8975f5c5SAndroid Build Coastguard Worker gl::Extents fbSize = sourceFramebufferGL->getState().getReadAttachment()->getSize();
718*8975f5c5SAndroid Build Coastguard Worker
719*8975f5c5SAndroid Build Coastguard Worker // Did the read area go outside the framebuffer?
720*8975f5c5SAndroid Build Coastguard Worker bool outside = sourceArea.x < 0 || sourceArea.y < 0 ||
721*8975f5c5SAndroid Build Coastguard Worker sourceArea.x + sourceArea.width > fbSize.width ||
722*8975f5c5SAndroid Build Coastguard Worker sourceArea.y + sourceArea.height > fbSize.height;
723*8975f5c5SAndroid Build Coastguard Worker
724*8975f5c5SAndroid Build Coastguard Worker // TODO: Find a way to initialize the texture entirely in the gl level with ensureInitialized.
725*8975f5c5SAndroid Build Coastguard Worker // Right now there is no easy way to pre-fill the texture when it is being redefined with
726*8975f5c5SAndroid Build Coastguard Worker // partially uninitialized data.
727*8975f5c5SAndroid Build Coastguard Worker bool requiresInitialization =
728*8975f5c5SAndroid Build Coastguard Worker outside && (context->isRobustResourceInitEnabled() || context->isWebGL());
729*8975f5c5SAndroid Build Coastguard Worker
730*8975f5c5SAndroid Build Coastguard Worker // When robust resource initialization is enabled, the area outside the framebuffer must be
731*8975f5c5SAndroid Build Coastguard Worker // zeroed. We just zero the whole thing before copying into the area that overlaps the
732*8975f5c5SAndroid Build Coastguard Worker // framebuffer.
733*8975f5c5SAndroid Build Coastguard Worker if (requiresInitialization)
734*8975f5c5SAndroid Build Coastguard Worker {
735*8975f5c5SAndroid Build Coastguard Worker GLuint pixelBytes =
736*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat, type).pixelBytes;
737*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *zero;
738*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_ALLOC(
739*8975f5c5SAndroid Build Coastguard Worker contextGL,
740*8975f5c5SAndroid Build Coastguard Worker context->getZeroFilledBuffer(sourceArea.width * sourceArea.height * pixelBytes, &zero));
741*8975f5c5SAndroid Build Coastguard Worker
742*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState unpack;
743*8975f5c5SAndroid Build Coastguard Worker unpack.alignment = 1;
744*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, unpack));
745*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackBuffer(context, nullptr));
746*8975f5c5SAndroid Build Coastguard Worker
747*8975f5c5SAndroid Build Coastguard Worker // getImplementationColorReadType aligns the type with ES client version
748*8975f5c5SAndroid Build Coastguard Worker if (type == GL_HALF_FLOAT_OES && functions->standard == STANDARD_GL_DESKTOP)
749*8975f5c5SAndroid Build Coastguard Worker {
750*8975f5c5SAndroid Build Coastguard Worker type = GL_HALF_FLOAT;
751*8975f5c5SAndroid Build Coastguard Worker }
752*8975f5c5SAndroid Build Coastguard Worker
753*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
754*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage2D(ToGLenum(target), static_cast<GLint>(level),
755*8975f5c5SAndroid Build Coastguard Worker copyTexImageFormat.internalFormat, sourceArea.width,
756*8975f5c5SAndroid Build Coastguard Worker sourceArea.height, 0,
757*8975f5c5SAndroid Build Coastguard Worker gl::GetUnsizedFormat(copyTexImageFormat.internalFormat),
758*8975f5c5SAndroid Build Coastguard Worker type, zero->data()));
759*8975f5c5SAndroid Build Coastguard Worker }
760*8975f5c5SAndroid Build Coastguard Worker
761*8975f5c5SAndroid Build Coastguard Worker // Clip source area to framebuffer and copy if remaining area is not empty.
762*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
763*8975f5c5SAndroid Build Coastguard Worker if (ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
764*8975f5c5SAndroid Build Coastguard Worker {
765*8975f5c5SAndroid Build Coastguard Worker // If fbo's read buffer and the target texture are the same texture but different levels,
766*8975f5c5SAndroid Build Coastguard Worker // and if the read buffer is a non-base texture level, then implementations glTexImage2D
767*8975f5c5SAndroid Build Coastguard Worker // may change the target texture and make the original texture mipmap incomplete, which in
768*8975f5c5SAndroid Build Coastguard Worker // turn makes the fbo incomplete.
769*8975f5c5SAndroid Build Coastguard Worker // To avoid that, we clamp BASE_LEVEL and MAX_LEVEL to the same texture level as the fbo's
770*8975f5c5SAndroid Build Coastguard Worker // read buffer attachment. See http://crbug.com/797235
771*8975f5c5SAndroid Build Coastguard Worker const gl::FramebufferAttachment *readBuffer = source->getReadColorAttachment();
772*8975f5c5SAndroid Build Coastguard Worker if (readBuffer && readBuffer->type() == GL_TEXTURE)
773*8975f5c5SAndroid Build Coastguard Worker {
774*8975f5c5SAndroid Build Coastguard Worker TextureGL *sourceTexture = GetImplAs<TextureGL>(readBuffer->getTexture());
775*8975f5c5SAndroid Build Coastguard Worker if (sourceTexture && sourceTexture->mTextureID == mTextureID)
776*8975f5c5SAndroid Build Coastguard Worker {
777*8975f5c5SAndroid Build Coastguard Worker GLuint attachedTextureLevel = readBuffer->mipLevel();
778*8975f5c5SAndroid Build Coastguard Worker if (attachedTextureLevel != mState.getEffectiveBaseLevel())
779*8975f5c5SAndroid Build Coastguard Worker {
780*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setBaseLevel(context, attachedTextureLevel));
781*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setMaxLevel(context, attachedTextureLevel));
782*8975f5c5SAndroid Build Coastguard Worker }
783*8975f5c5SAndroid Build Coastguard Worker }
784*8975f5c5SAndroid Build Coastguard Worker }
785*8975f5c5SAndroid Build Coastguard Worker
786*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL levelInfo =
787*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, copyTexImageFormat.internalFormat);
788*8975f5c5SAndroid Build Coastguard Worker gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
789*8975f5c5SAndroid Build Coastguard Worker
790*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.lumaWorkaround.enabled)
791*8975f5c5SAndroid Build Coastguard Worker {
792*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
793*8975f5c5SAndroid Build Coastguard Worker
794*8975f5c5SAndroid Build Coastguard Worker if (requiresInitialization)
795*8975f5c5SAndroid Build Coastguard Worker {
796*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copySubImageToLUMAWorkaroundTexture(
797*8975f5c5SAndroid Build Coastguard Worker context, mTextureID, getType(), target, levelInfo.sourceFormat, level,
798*8975f5c5SAndroid Build Coastguard Worker destOffset, clippedArea, source));
799*8975f5c5SAndroid Build Coastguard Worker }
800*8975f5c5SAndroid Build Coastguard Worker else
801*8975f5c5SAndroid Build Coastguard Worker {
802*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copyImageToLUMAWorkaroundTexture(
803*8975f5c5SAndroid Build Coastguard Worker context, mTextureID, getType(), target, levelInfo.sourceFormat, level,
804*8975f5c5SAndroid Build Coastguard Worker clippedArea, copyTexImageFormat.internalFormat, source));
805*8975f5c5SAndroid Build Coastguard Worker }
806*8975f5c5SAndroid Build Coastguard Worker }
807*8975f5c5SAndroid Build Coastguard Worker else
808*8975f5c5SAndroid Build Coastguard Worker {
809*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage2D(getType()));
810*8975f5c5SAndroid Build Coastguard Worker stateManager->bindFramebuffer(GL_READ_FRAMEBUFFER,
811*8975f5c5SAndroid Build Coastguard Worker sourceFramebufferGL->getFramebufferID());
812*8975f5c5SAndroid Build Coastguard Worker if (features.emulateCopyTexImage2DFromRenderbuffers.enabled && readBuffer &&
813*8975f5c5SAndroid Build Coastguard Worker readBuffer->type() == GL_RENDERBUFFER)
814*8975f5c5SAndroid Build Coastguard Worker {
815*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
816*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->blitColorBufferWithShader(
817*8975f5c5SAndroid Build Coastguard Worker context, source, mTextureID, target, level, clippedArea,
818*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle(destOffset.x, destOffset.y, clippedArea.width,
819*8975f5c5SAndroid Build Coastguard Worker clippedArea.height),
820*8975f5c5SAndroid Build Coastguard Worker GL_NEAREST, true));
821*8975f5c5SAndroid Build Coastguard Worker }
822*8975f5c5SAndroid Build Coastguard Worker else if (requiresInitialization)
823*8975f5c5SAndroid Build Coastguard Worker {
824*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->copyTexSubImage2D(
825*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), destOffset.x,
826*8975f5c5SAndroid Build Coastguard Worker destOffset.y, clippedArea.x, clippedArea.y,
827*8975f5c5SAndroid Build Coastguard Worker clippedArea.width, clippedArea.height));
828*8975f5c5SAndroid Build Coastguard Worker }
829*8975f5c5SAndroid Build Coastguard Worker else
830*8975f5c5SAndroid Build Coastguard Worker {
831*8975f5c5SAndroid Build Coastguard Worker if (features.emulateCopyTexImage2D.enabled)
832*8975f5c5SAndroid Build Coastguard Worker {
833*8975f5c5SAndroid Build Coastguard Worker if (type == GL_HALF_FLOAT_OES && functions->standard == STANDARD_GL_DESKTOP)
834*8975f5c5SAndroid Build Coastguard Worker {
835*8975f5c5SAndroid Build Coastguard Worker type = GL_HALF_FLOAT;
836*8975f5c5SAndroid Build Coastguard Worker }
837*8975f5c5SAndroid Build Coastguard Worker
838*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
839*8975f5c5SAndroid Build Coastguard Worker context,
840*8975f5c5SAndroid Build Coastguard Worker functions->texImage2D(
841*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level),
842*8975f5c5SAndroid Build Coastguard Worker copyTexImageFormat.internalFormat, sourceArea.width, sourceArea.height,
843*8975f5c5SAndroid Build Coastguard Worker 0, gl::GetUnsizedFormat(copyTexImageFormat.internalFormat), type,
844*8975f5c5SAndroid Build Coastguard Worker nullptr));
845*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
846*8975f5c5SAndroid Build Coastguard Worker context,
847*8975f5c5SAndroid Build Coastguard Worker functions->copyTexSubImage2D(ToGLenum(target), static_cast<GLint>(level), 0,
848*8975f5c5SAndroid Build Coastguard Worker 0, sourceArea.x, sourceArea.y,
849*8975f5c5SAndroid Build Coastguard Worker sourceArea.width, sourceArea.height));
850*8975f5c5SAndroid Build Coastguard Worker }
851*8975f5c5SAndroid Build Coastguard Worker else
852*8975f5c5SAndroid Build Coastguard Worker {
853*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
854*8975f5c5SAndroid Build Coastguard Worker context, functions->copyTexImage2D(
855*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level),
856*8975f5c5SAndroid Build Coastguard Worker copyTexImageFormat.internalFormat, sourceArea.x, sourceArea.y,
857*8975f5c5SAndroid Build Coastguard Worker sourceArea.width, sourceArea.height, 0));
858*8975f5c5SAndroid Build Coastguard Worker }
859*8975f5c5SAndroid Build Coastguard Worker }
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, level, 1, levelInfo);
862*8975f5c5SAndroid Build Coastguard Worker }
863*8975f5c5SAndroid Build Coastguard Worker
864*8975f5c5SAndroid Build Coastguard Worker if (features.flushBeforeDeleteTextureIfCopiedTo.enabled)
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker contextGL->setNeedsFlushBeforeDeleteTextures();
867*8975f5c5SAndroid Build Coastguard Worker }
868*8975f5c5SAndroid Build Coastguard Worker
869*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
870*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
871*8975f5c5SAndroid Build Coastguard Worker }
872*8975f5c5SAndroid Build Coastguard Worker
copySubImage(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,const gl::Rectangle & sourceArea,gl::Framebuffer * source)873*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::copySubImage(const gl::Context *context,
874*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
875*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
876*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
877*8975f5c5SAndroid Build Coastguard Worker gl::Framebuffer *source)
878*8975f5c5SAndroid Build Coastguard Worker {
879*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
880*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
881*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
882*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
883*8975f5c5SAndroid Build Coastguard Worker
884*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
885*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
886*8975f5c5SAndroid Build Coastguard Worker const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source);
887*8975f5c5SAndroid Build Coastguard Worker
888*8975f5c5SAndroid Build Coastguard Worker // Clip source area to framebuffer.
889*8975f5c5SAndroid Build Coastguard Worker const gl::Extents fbSize = sourceFramebufferGL->getState().getReadAttachment()->getSize();
890*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle clippedArea;
891*8975f5c5SAndroid Build Coastguard Worker if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
892*8975f5c5SAndroid Build Coastguard Worker {
893*8975f5c5SAndroid Build Coastguard Worker // nothing to do
894*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
895*8975f5c5SAndroid Build Coastguard Worker }
896*8975f5c5SAndroid Build Coastguard Worker gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
897*8975f5c5SAndroid Build Coastguard Worker destOffset.y + clippedArea.y - sourceArea.y, destOffset.z);
898*8975f5c5SAndroid Build Coastguard Worker
899*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
900*8975f5c5SAndroid Build Coastguard Worker GLenum framebufferTarget =
901*8975f5c5SAndroid Build Coastguard Worker stateManager->getHasSeparateFramebufferBindings() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER;
902*8975f5c5SAndroid Build Coastguard Worker stateManager->bindFramebuffer(framebufferTarget, sourceFramebufferGL->getFramebufferID());
903*8975f5c5SAndroid Build Coastguard Worker
904*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &levelInfo = getLevelInfo(target, level);
905*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.lumaWorkaround.enabled)
906*8975f5c5SAndroid Build Coastguard Worker {
907*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
908*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copySubImageToLUMAWorkaroundTexture(
909*8975f5c5SAndroid Build Coastguard Worker context, mTextureID, getType(), target, levelInfo.sourceFormat, level, clippedOffset,
910*8975f5c5SAndroid Build Coastguard Worker clippedArea, source));
911*8975f5c5SAndroid Build Coastguard Worker }
912*8975f5c5SAndroid Build Coastguard Worker else
913*8975f5c5SAndroid Build Coastguard Worker {
914*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
915*8975f5c5SAndroid Build Coastguard Worker {
916*8975f5c5SAndroid Build Coastguard Worker ASSERT(clippedOffset.z == 0);
917*8975f5c5SAndroid Build Coastguard Worker if (features.emulateCopyTexImage2DFromRenderbuffers.enabled &&
918*8975f5c5SAndroid Build Coastguard Worker source->getReadColorAttachment() &&
919*8975f5c5SAndroid Build Coastguard Worker source->getReadColorAttachment()->type() == GL_RENDERBUFFER)
920*8975f5c5SAndroid Build Coastguard Worker {
921*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
922*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->blitColorBufferWithShader(
923*8975f5c5SAndroid Build Coastguard Worker context, source, mTextureID, target, level, clippedArea,
924*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle(clippedOffset.x, clippedOffset.y, clippedArea.width,
925*8975f5c5SAndroid Build Coastguard Worker clippedArea.height),
926*8975f5c5SAndroid Build Coastguard Worker GL_NEAREST, true));
927*8975f5c5SAndroid Build Coastguard Worker }
928*8975f5c5SAndroid Build Coastguard Worker else
929*8975f5c5SAndroid Build Coastguard Worker {
930*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->copyTexSubImage2D(
931*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level),
932*8975f5c5SAndroid Build Coastguard Worker clippedOffset.x, clippedOffset.y, clippedArea.x,
933*8975f5c5SAndroid Build Coastguard Worker clippedArea.y, clippedArea.width, clippedArea.height));
934*8975f5c5SAndroid Build Coastguard Worker }
935*8975f5c5SAndroid Build Coastguard Worker }
936*8975f5c5SAndroid Build Coastguard Worker else
937*8975f5c5SAndroid Build Coastguard Worker {
938*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
939*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->copyTexSubImage3D(
940*8975f5c5SAndroid Build Coastguard Worker ToGLenum(target), static_cast<GLint>(level), clippedOffset.x,
941*8975f5c5SAndroid Build Coastguard Worker clippedOffset.y, clippedOffset.z, clippedArea.x,
942*8975f5c5SAndroid Build Coastguard Worker clippedArea.y, clippedArea.width, clippedArea.height));
943*8975f5c5SAndroid Build Coastguard Worker }
944*8975f5c5SAndroid Build Coastguard Worker }
945*8975f5c5SAndroid Build Coastguard Worker
946*8975f5c5SAndroid Build Coastguard Worker if (features.flushBeforeDeleteTextureIfCopiedTo.enabled)
947*8975f5c5SAndroid Build Coastguard Worker {
948*8975f5c5SAndroid Build Coastguard Worker contextGL->setNeedsFlushBeforeDeleteTextures();
949*8975f5c5SAndroid Build Coastguard Worker }
950*8975f5c5SAndroid Build Coastguard Worker
951*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
952*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
953*8975f5c5SAndroid Build Coastguard Worker }
954*8975f5c5SAndroid Build Coastguard Worker
copyTexture(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,GLenum type,GLint sourceLevel,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)955*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::copyTexture(const gl::Context *context,
956*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
957*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
958*8975f5c5SAndroid Build Coastguard Worker GLenum type,
959*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
960*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
961*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
962*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
963*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
966*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
967*8975f5c5SAndroid Build Coastguard Worker const TextureGL *sourceGL = GetImplAs<TextureGL>(source);
968*8975f5c5SAndroid Build Coastguard Worker const gl::ImageDesc &sourceImageDesc =
969*8975f5c5SAndroid Build Coastguard Worker sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
970*8975f5c5SAndroid Build Coastguard Worker gl::Rectangle sourceArea(0, 0, sourceImageDesc.size.width, sourceImageDesc.size.height);
971*8975f5c5SAndroid Build Coastguard Worker
972*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(reserveTexImageToBeFilled(context, target, level, internalFormat,
973*8975f5c5SAndroid Build Coastguard Worker sourceImageDesc.size, gl::GetUnsizedFormat(internalFormat),
974*8975f5c5SAndroid Build Coastguard Worker type));
975*8975f5c5SAndroid Build Coastguard Worker
976*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
977*8975f5c5SAndroid Build Coastguard Worker return copySubTextureHelper(context, target, level, gl::Offset(0, 0, 0), sourceLevel,
978*8975f5c5SAndroid Build Coastguard Worker sourceArea, destFormatInfo, unpackFlipY, unpackPremultiplyAlpha,
979*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha, source);
980*8975f5c5SAndroid Build Coastguard Worker }
981*8975f5c5SAndroid Build Coastguard Worker
copySubTexture(const gl::Context * context,const gl::ImageIndex & index,const gl::Offset & destOffset,GLint sourceLevel,const gl::Box & sourceBox,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)982*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::copySubTexture(const gl::Context *context,
983*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
984*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
985*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
986*8975f5c5SAndroid Build Coastguard Worker const gl::Box &sourceBox,
987*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
988*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
989*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
990*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
991*8975f5c5SAndroid Build Coastguard Worker {
992*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
993*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
994*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &destFormatInfo = *mState.getImageDesc(target, level).format.info;
995*8975f5c5SAndroid Build Coastguard Worker return copySubTextureHelper(context, target, level, destOffset, sourceLevel, sourceBox.toRect(),
996*8975f5c5SAndroid Build Coastguard Worker destFormatInfo, unpackFlipY, unpackPremultiplyAlpha,
997*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha, source);
998*8975f5c5SAndroid Build Coastguard Worker }
999*8975f5c5SAndroid Build Coastguard Worker
copySubTextureHelper(const gl::Context * context,gl::TextureTarget target,size_t level,const gl::Offset & destOffset,GLint sourceLevel,const gl::Rectangle & sourceArea,const gl::InternalFormat & destFormat,bool unpackFlipY,bool unpackPremultiplyAlpha,bool unpackUnmultiplyAlpha,const gl::Texture * source)1000*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::copySubTextureHelper(const gl::Context *context,
1001*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
1002*8975f5c5SAndroid Build Coastguard Worker size_t level,
1003*8975f5c5SAndroid Build Coastguard Worker const gl::Offset &destOffset,
1004*8975f5c5SAndroid Build Coastguard Worker GLint sourceLevel,
1005*8975f5c5SAndroid Build Coastguard Worker const gl::Rectangle &sourceArea,
1006*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &destFormat,
1007*8975f5c5SAndroid Build Coastguard Worker bool unpackFlipY,
1008*8975f5c5SAndroid Build Coastguard Worker bool unpackPremultiplyAlpha,
1009*8975f5c5SAndroid Build Coastguard Worker bool unpackUnmultiplyAlpha,
1010*8975f5c5SAndroid Build Coastguard Worker const gl::Texture *source)
1011*8975f5c5SAndroid Build Coastguard Worker {
1012*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
1013*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1014*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1015*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
1016*8975f5c5SAndroid Build Coastguard Worker
1017*8975f5c5SAndroid Build Coastguard Worker TextureGL *sourceGL = GetImplAs<TextureGL>(source);
1018*8975f5c5SAndroid Build Coastguard Worker const gl::ImageDesc &sourceImageDesc =
1019*8975f5c5SAndroid Build Coastguard Worker sourceGL->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
1020*8975f5c5SAndroid Build Coastguard Worker
1021*8975f5c5SAndroid Build Coastguard Worker if (features.flushBeforeDeleteTextureIfCopiedTo.enabled)
1022*8975f5c5SAndroid Build Coastguard Worker {
1023*8975f5c5SAndroid Build Coastguard Worker // Conservatively indicate that this workaround is necessary. Not clear
1024*8975f5c5SAndroid Build Coastguard Worker // if it is on this code path, but added for symmetry.
1025*8975f5c5SAndroid Build Coastguard Worker contextGL->setNeedsFlushBeforeDeleteTextures();
1026*8975f5c5SAndroid Build Coastguard Worker }
1027*8975f5c5SAndroid Build Coastguard Worker
1028*8975f5c5SAndroid Build Coastguard Worker // Check is this is a simple copySubTexture that can be done with a copyTexSubImage
1029*8975f5c5SAndroid Build Coastguard Worker ASSERT(sourceGL->getType() == gl::TextureType::_2D ||
1030*8975f5c5SAndroid Build Coastguard Worker source->getType() == gl::TextureType::External ||
1031*8975f5c5SAndroid Build Coastguard Worker source->getType() == gl::TextureType::Rectangle);
1032*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &sourceLevelInfo =
1033*8975f5c5SAndroid Build Coastguard Worker sourceGL->getLevelInfo(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
1034*8975f5c5SAndroid Build Coastguard Worker bool needsLumaWorkaround = sourceLevelInfo.lumaWorkaround.enabled;
1035*8975f5c5SAndroid Build Coastguard Worker
1036*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &sourceFormatInfo = *sourceImageDesc.format.info;
1037*8975f5c5SAndroid Build Coastguard Worker GLenum sourceFormat = sourceFormatInfo.format;
1038*8975f5c5SAndroid Build Coastguard Worker bool sourceFormatContainSupersetOfDestFormat =
1039*8975f5c5SAndroid Build Coastguard Worker (sourceFormat == destFormat.format && sourceFormat != GL_BGRA_EXT) ||
1040*8975f5c5SAndroid Build Coastguard Worker (sourceFormat == GL_RGBA && destFormat.format == GL_RGB);
1041*8975f5c5SAndroid Build Coastguard Worker bool sourceSRGB = sourceFormatInfo.colorEncoding == GL_SRGB;
1042*8975f5c5SAndroid Build Coastguard Worker
1043*8975f5c5SAndroid Build Coastguard Worker GLenum sourceComponentType = sourceFormatInfo.componentType;
1044*8975f5c5SAndroid Build Coastguard Worker GLenum destComponentType = destFormat.componentType;
1045*8975f5c5SAndroid Build Coastguard Worker bool destSRGB = destFormat.colorEncoding == GL_SRGB;
1046*8975f5c5SAndroid Build Coastguard Worker if (!unpackFlipY && unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !needsLumaWorkaround &&
1047*8975f5c5SAndroid Build Coastguard Worker sourceFormatContainSupersetOfDestFormat && sourceComponentType == destComponentType &&
1048*8975f5c5SAndroid Build Coastguard Worker !destSRGB && !sourceSRGB && sourceGL->getType() == gl::TextureType::_2D)
1049*8975f5c5SAndroid Build Coastguard Worker {
1050*8975f5c5SAndroid Build Coastguard Worker bool copySucceeded = false;
1051*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copyTexSubImage(context, sourceGL, sourceLevel, this, target, level,
1052*8975f5c5SAndroid Build Coastguard Worker sourceArea, destOffset, ©Succeeded));
1053*8975f5c5SAndroid Build Coastguard Worker if (copySucceeded)
1054*8975f5c5SAndroid Build Coastguard Worker {
1055*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1056*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1057*8975f5c5SAndroid Build Coastguard Worker }
1058*8975f5c5SAndroid Build Coastguard Worker }
1059*8975f5c5SAndroid Build Coastguard Worker
1060*8975f5c5SAndroid Build Coastguard Worker // Check if the destination is renderable and copy on the GPU
1061*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &destLevelInfo = getLevelInfo(target, level);
1062*8975f5c5SAndroid Build Coastguard Worker // todo(jonahr): http://crbug.com/773861
1063*8975f5c5SAndroid Build Coastguard Worker // Behavior for now is to fallback to CPU readback implementation if the destination texture
1064*8975f5c5SAndroid Build Coastguard Worker // is a luminance format. The correct solution is to handle both source and destination in the
1065*8975f5c5SAndroid Build Coastguard Worker // luma workaround.
1066*8975f5c5SAndroid Build Coastguard Worker if (!destSRGB && !destLevelInfo.lumaWorkaround.enabled &&
1067*8975f5c5SAndroid Build Coastguard Worker nativegl::SupportsNativeRendering(functions, getType(), destLevelInfo.nativeInternalFormat))
1068*8975f5c5SAndroid Build Coastguard Worker {
1069*8975f5c5SAndroid Build Coastguard Worker bool copySucceeded = false;
1070*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copySubTexture(
1071*8975f5c5SAndroid Build Coastguard Worker context, sourceGL, sourceLevel, sourceComponentType, mTextureID, target, level,
1072*8975f5c5SAndroid Build Coastguard Worker destComponentType, sourceImageDesc.size, sourceArea, destOffset, needsLumaWorkaround,
1073*8975f5c5SAndroid Build Coastguard Worker sourceLevelInfo.sourceFormat, unpackFlipY, unpackPremultiplyAlpha,
1074*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha, sourceSRGB, ©Succeeded));
1075*8975f5c5SAndroid Build Coastguard Worker if (copySucceeded)
1076*8975f5c5SAndroid Build Coastguard Worker {
1077*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1078*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1079*8975f5c5SAndroid Build Coastguard Worker }
1080*8975f5c5SAndroid Build Coastguard Worker }
1081*8975f5c5SAndroid Build Coastguard Worker
1082*8975f5c5SAndroid Build Coastguard Worker // Fall back to CPU-readback
1083*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->copySubTextureCPUReadback(
1084*8975f5c5SAndroid Build Coastguard Worker context, sourceGL, sourceLevel, sourceFormatInfo.sizedInternalFormat, this, target, level,
1085*8975f5c5SAndroid Build Coastguard Worker destFormat.format, destFormat.type, sourceImageDesc.size, sourceArea, destOffset,
1086*8975f5c5SAndroid Build Coastguard Worker needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY, unpackPremultiplyAlpha,
1087*8975f5c5SAndroid Build Coastguard Worker unpackUnmultiplyAlpha));
1088*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1089*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1090*8975f5c5SAndroid Build Coastguard Worker }
1091*8975f5c5SAndroid Build Coastguard Worker
setStorage(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size)1092*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setStorage(const gl::Context *context,
1093*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1094*8975f5c5SAndroid Build Coastguard Worker size_t levels,
1095*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1096*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size)
1097*8975f5c5SAndroid Build Coastguard Worker {
1098*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
1099*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1100*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1101*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1102*8975f5c5SAndroid Build Coastguard Worker
1103*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
1104*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalFormat);
1105*8975f5c5SAndroid Build Coastguard Worker nativegl::TexStorageFormat texStorageFormat =
1106*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexStorageFormat(functions, features, internalFormat);
1107*8975f5c5SAndroid Build Coastguard Worker
1108*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1109*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
1110*8975f5c5SAndroid Build Coastguard Worker {
1111*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
1112*8975f5c5SAndroid Build Coastguard Worker if (functions->texStorage2D)
1113*8975f5c5SAndroid Build Coastguard Worker {
1114*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1115*8975f5c5SAndroid Build Coastguard Worker context,
1116*8975f5c5SAndroid Build Coastguard Worker functions->texStorage2D(ToGLenum(type), static_cast<GLsizei>(levels),
1117*8975f5c5SAndroid Build Coastguard Worker texStorageFormat.internalFormat, size.width, size.height));
1118*8975f5c5SAndroid Build Coastguard Worker }
1119*8975f5c5SAndroid Build Coastguard Worker else
1120*8975f5c5SAndroid Build Coastguard Worker {
1121*8975f5c5SAndroid Build Coastguard Worker // Make sure no pixel unpack buffer is bound
1122*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
1123*8975f5c5SAndroid Build Coastguard Worker
1124*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
1125*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalFormat);
1126*8975f5c5SAndroid Build Coastguard Worker
1127*8975f5c5SAndroid Build Coastguard Worker // Internal format must be sized
1128*8975f5c5SAndroid Build Coastguard Worker ASSERT(internalFormatInfo.sized);
1129*8975f5c5SAndroid Build Coastguard Worker
1130*8975f5c5SAndroid Build Coastguard Worker for (size_t level = 0; level < levels; level++)
1131*8975f5c5SAndroid Build Coastguard Worker {
1132*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(size.width >> level, 1),
1133*8975f5c5SAndroid Build Coastguard Worker std::max(size.height >> level, 1), 1);
1134*8975f5c5SAndroid Build Coastguard Worker
1135*8975f5c5SAndroid Build Coastguard Worker if (getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle)
1136*8975f5c5SAndroid Build Coastguard Worker {
1137*8975f5c5SAndroid Build Coastguard Worker if (internalFormatInfo.compressed)
1138*8975f5c5SAndroid Build Coastguard Worker {
1139*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
1140*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedSubTexImageFormat(functions, features,
1141*8975f5c5SAndroid Build Coastguard Worker internalFormat);
1142*8975f5c5SAndroid Build Coastguard Worker
1143*8975f5c5SAndroid Build Coastguard Worker GLuint dataSize = 0;
1144*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(
1145*8975f5c5SAndroid Build Coastguard Worker contextGL,
1146*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.computeCompressedImageSize(levelSize, &dataSize));
1147*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1148*8975f5c5SAndroid Build Coastguard Worker context,
1149*8975f5c5SAndroid Build Coastguard Worker functions->compressedTexImage2D(
1150*8975f5c5SAndroid Build Coastguard Worker ToGLenum(type), static_cast<GLint>(level),
1151*8975f5c5SAndroid Build Coastguard Worker compressedTexImageFormat.format, levelSize.width, levelSize.height,
1152*8975f5c5SAndroid Build Coastguard Worker 0, static_cast<GLsizei>(dataSize), nullptr));
1153*8975f5c5SAndroid Build Coastguard Worker }
1154*8975f5c5SAndroid Build Coastguard Worker else
1155*8975f5c5SAndroid Build Coastguard Worker {
1156*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
1157*8975f5c5SAndroid Build Coastguard Worker functions, features, internalFormat, internalFormatInfo.format,
1158*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type);
1159*8975f5c5SAndroid Build Coastguard Worker
1160*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1161*8975f5c5SAndroid Build Coastguard Worker context,
1162*8975f5c5SAndroid Build Coastguard Worker functions->texImage2D(ToGLenum(type), static_cast<GLint>(level),
1163*8975f5c5SAndroid Build Coastguard Worker texImageFormat.internalFormat, levelSize.width,
1164*8975f5c5SAndroid Build Coastguard Worker levelSize.height, 0, texImageFormat.format,
1165*8975f5c5SAndroid Build Coastguard Worker texImageFormat.type, nullptr));
1166*8975f5c5SAndroid Build Coastguard Worker }
1167*8975f5c5SAndroid Build Coastguard Worker }
1168*8975f5c5SAndroid Build Coastguard Worker else
1169*8975f5c5SAndroid Build Coastguard Worker {
1170*8975f5c5SAndroid Build Coastguard Worker ASSERT(getType() == gl::TextureType::CubeMap);
1171*8975f5c5SAndroid Build Coastguard Worker for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
1172*8975f5c5SAndroid Build Coastguard Worker {
1173*8975f5c5SAndroid Build Coastguard Worker if (internalFormatInfo.compressed)
1174*8975f5c5SAndroid Build Coastguard Worker {
1175*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
1176*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedSubTexImageFormat(functions, features,
1177*8975f5c5SAndroid Build Coastguard Worker internalFormat);
1178*8975f5c5SAndroid Build Coastguard Worker
1179*8975f5c5SAndroid Build Coastguard Worker GLuint dataSize = 0;
1180*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL,
1181*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.computeCompressedImageSize(
1182*8975f5c5SAndroid Build Coastguard Worker levelSize, &dataSize));
1183*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1184*8975f5c5SAndroid Build Coastguard Worker context,
1185*8975f5c5SAndroid Build Coastguard Worker functions->compressedTexImage2D(
1186*8975f5c5SAndroid Build Coastguard Worker ToGLenum(face), static_cast<GLint>(level),
1187*8975f5c5SAndroid Build Coastguard Worker compressedTexImageFormat.format, levelSize.width,
1188*8975f5c5SAndroid Build Coastguard Worker levelSize.height, 0, static_cast<GLsizei>(dataSize), nullptr));
1189*8975f5c5SAndroid Build Coastguard Worker }
1190*8975f5c5SAndroid Build Coastguard Worker else
1191*8975f5c5SAndroid Build Coastguard Worker {
1192*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
1193*8975f5c5SAndroid Build Coastguard Worker functions, features, internalFormat, internalFormatInfo.format,
1194*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type);
1195*8975f5c5SAndroid Build Coastguard Worker
1196*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1197*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage2D(
1198*8975f5c5SAndroid Build Coastguard Worker ToGLenum(face), static_cast<GLint>(level),
1199*8975f5c5SAndroid Build Coastguard Worker texImageFormat.internalFormat, levelSize.width,
1200*8975f5c5SAndroid Build Coastguard Worker levelSize.height, 0, texImageFormat.format,
1201*8975f5c5SAndroid Build Coastguard Worker texImageFormat.type, nullptr));
1202*8975f5c5SAndroid Build Coastguard Worker }
1203*8975f5c5SAndroid Build Coastguard Worker }
1204*8975f5c5SAndroid Build Coastguard Worker }
1205*8975f5c5SAndroid Build Coastguard Worker }
1206*8975f5c5SAndroid Build Coastguard Worker }
1207*8975f5c5SAndroid Build Coastguard Worker }
1208*8975f5c5SAndroid Build Coastguard Worker else
1209*8975f5c5SAndroid Build Coastguard Worker {
1210*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
1211*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo =
1212*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalFormat);
1213*8975f5c5SAndroid Build Coastguard Worker const bool bypassTexStorage3D = type == gl::TextureType::_3D &&
1214*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.compressed &&
1215*8975f5c5SAndroid Build Coastguard Worker features.emulateImmutableCompressedTexture3D.enabled;
1216*8975f5c5SAndroid Build Coastguard Worker if (functions->texStorage3D && !bypassTexStorage3D)
1217*8975f5c5SAndroid Build Coastguard Worker {
1218*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1219*8975f5c5SAndroid Build Coastguard Worker context, functions->texStorage3D(ToGLenum(type), static_cast<GLsizei>(levels),
1220*8975f5c5SAndroid Build Coastguard Worker texStorageFormat.internalFormat, size.width,
1221*8975f5c5SAndroid Build Coastguard Worker size.height, size.depth));
1222*8975f5c5SAndroid Build Coastguard Worker }
1223*8975f5c5SAndroid Build Coastguard Worker else
1224*8975f5c5SAndroid Build Coastguard Worker {
1225*8975f5c5SAndroid Build Coastguard Worker // Make sure no pixel unpack buffer is bound
1226*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
1227*8975f5c5SAndroid Build Coastguard Worker
1228*8975f5c5SAndroid Build Coastguard Worker // Internal format must be sized
1229*8975f5c5SAndroid Build Coastguard Worker ASSERT(internalFormatInfo.sized);
1230*8975f5c5SAndroid Build Coastguard Worker
1231*8975f5c5SAndroid Build Coastguard Worker for (GLsizei i = 0; i < static_cast<GLsizei>(levels); i++)
1232*8975f5c5SAndroid Build Coastguard Worker {
1233*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(
1234*8975f5c5SAndroid Build Coastguard Worker std::max(size.width >> i, 1), std::max(size.height >> i, 1),
1235*8975f5c5SAndroid Build Coastguard Worker getType() == gl::TextureType::_3D ? std::max(size.depth >> i, 1) : size.depth);
1236*8975f5c5SAndroid Build Coastguard Worker
1237*8975f5c5SAndroid Build Coastguard Worker if (internalFormatInfo.compressed)
1238*8975f5c5SAndroid Build Coastguard Worker {
1239*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexSubImageFormat compressedTexImageFormat =
1240*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedSubTexImageFormat(functions, features,
1241*8975f5c5SAndroid Build Coastguard Worker internalFormat);
1242*8975f5c5SAndroid Build Coastguard Worker
1243*8975f5c5SAndroid Build Coastguard Worker GLuint dataSize = 0;
1244*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, internalFormatInfo.computeCompressedImageSize(
1245*8975f5c5SAndroid Build Coastguard Worker levelSize, &dataSize));
1246*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1247*8975f5c5SAndroid Build Coastguard Worker context, functions->compressedTexImage3D(
1248*8975f5c5SAndroid Build Coastguard Worker ToGLenum(type), i, compressedTexImageFormat.format,
1249*8975f5c5SAndroid Build Coastguard Worker levelSize.width, levelSize.height, levelSize.depth, 0,
1250*8975f5c5SAndroid Build Coastguard Worker static_cast<GLsizei>(dataSize), nullptr));
1251*8975f5c5SAndroid Build Coastguard Worker }
1252*8975f5c5SAndroid Build Coastguard Worker else
1253*8975f5c5SAndroid Build Coastguard Worker {
1254*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
1255*8975f5c5SAndroid Build Coastguard Worker functions, features, internalFormat, internalFormatInfo.format,
1256*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.type);
1257*8975f5c5SAndroid Build Coastguard Worker
1258*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1259*8975f5c5SAndroid Build Coastguard Worker context,
1260*8975f5c5SAndroid Build Coastguard Worker functions->texImage3D(ToGLenum(type), i, texImageFormat.internalFormat,
1261*8975f5c5SAndroid Build Coastguard Worker levelSize.width, levelSize.height, levelSize.depth, 0,
1262*8975f5c5SAndroid Build Coastguard Worker texImageFormat.format, texImageFormat.type, nullptr));
1263*8975f5c5SAndroid Build Coastguard Worker }
1264*8975f5c5SAndroid Build Coastguard Worker }
1265*8975f5c5SAndroid Build Coastguard Worker }
1266*8975f5c5SAndroid Build Coastguard Worker }
1267*8975f5c5SAndroid Build Coastguard Worker
1268*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(
1269*8975f5c5SAndroid Build Coastguard Worker context, type, 0, levels,
1270*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texStorageFormat.internalFormat));
1271*8975f5c5SAndroid Build Coastguard Worker
1272*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1273*8975f5c5SAndroid Build Coastguard Worker }
1274*8975f5c5SAndroid Build Coastguard Worker
setImageExternal(const gl::Context * context,const gl::ImageIndex & index,GLenum internalFormat,const gl::Extents & size,GLenum format,GLenum type)1275*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setImageExternal(const gl::Context *context,
1276*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &index,
1277*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1278*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1279*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1280*8975f5c5SAndroid Build Coastguard Worker GLenum type)
1281*8975f5c5SAndroid Build Coastguard Worker {
1282*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1283*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1284*8975f5c5SAndroid Build Coastguard Worker
1285*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = index.getTarget();
1286*8975f5c5SAndroid Build Coastguard Worker size_t level = static_cast<size_t>(index.getLevelIndex());
1287*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
1288*8975f5c5SAndroid Build Coastguard Worker gl::GetInternalFormatInfo(internalFormat, type);
1289*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat =
1290*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexImageFormat(functions, features, internalFormat, format, type);
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, level, 1,
1293*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texImageFormat.internalFormat));
1294*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1295*8975f5c5SAndroid Build Coastguard Worker }
1296*8975f5c5SAndroid Build Coastguard Worker
setStorageMultisample(const gl::Context * context,gl::TextureType type,GLsizei samples,GLint internalformat,const gl::Extents & size,bool fixedSampleLocations)1297*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setStorageMultisample(const gl::Context *context,
1298*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1299*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
1300*8975f5c5SAndroid Build Coastguard Worker GLint internalformat,
1301*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1302*8975f5c5SAndroid Build Coastguard Worker bool fixedSampleLocations)
1303*8975f5c5SAndroid Build Coastguard Worker {
1304*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1305*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1306*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1307*8975f5c5SAndroid Build Coastguard Worker
1308*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
1309*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalformat);
1310*8975f5c5SAndroid Build Coastguard Worker nativegl::TexStorageFormat texStorageFormat =
1311*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexStorageFormat(functions, features, internalformat);
1312*8975f5c5SAndroid Build Coastguard Worker
1313*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1314*8975f5c5SAndroid Build Coastguard Worker
1315*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
1316*8975f5c5SAndroid Build Coastguard Worker {
1317*8975f5c5SAndroid Build Coastguard Worker ASSERT(size.depth == 1);
1318*8975f5c5SAndroid Build Coastguard Worker if (functions->texStorage2DMultisample)
1319*8975f5c5SAndroid Build Coastguard Worker {
1320*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1321*8975f5c5SAndroid Build Coastguard Worker context, functions->texStorage2DMultisample(
1322*8975f5c5SAndroid Build Coastguard Worker ToGLenum(type), samples, texStorageFormat.internalFormat, size.width,
1323*8975f5c5SAndroid Build Coastguard Worker size.height, gl::ConvertToGLBoolean(fixedSampleLocations)));
1324*8975f5c5SAndroid Build Coastguard Worker }
1325*8975f5c5SAndroid Build Coastguard Worker else
1326*8975f5c5SAndroid Build Coastguard Worker {
1327*8975f5c5SAndroid Build Coastguard Worker // texImage2DMultisample is similar to texStorage2DMultisample of es 3.1 core feature,
1328*8975f5c5SAndroid Build Coastguard Worker // On macos and some old drivers which doesn't support OpenGL ES 3.1, the function can
1329*8975f5c5SAndroid Build Coastguard Worker // be supported by ARB_texture_multisample or OpenGL 3.2 core feature.
1330*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1331*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage2DMultisample(
1332*8975f5c5SAndroid Build Coastguard Worker ToGLenum(type), samples, texStorageFormat.internalFormat, size.width,
1333*8975f5c5SAndroid Build Coastguard Worker size.height, gl::ConvertToGLBoolean(fixedSampleLocations)));
1334*8975f5c5SAndroid Build Coastguard Worker }
1335*8975f5c5SAndroid Build Coastguard Worker }
1336*8975f5c5SAndroid Build Coastguard Worker else
1337*8975f5c5SAndroid Build Coastguard Worker {
1338*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
1339*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1340*8975f5c5SAndroid Build Coastguard Worker context, functions->texStorage3DMultisample(
1341*8975f5c5SAndroid Build Coastguard Worker ToGLenum(type), samples, texStorageFormat.internalFormat, size.width,
1342*8975f5c5SAndroid Build Coastguard Worker size.height, size.depth, gl::ConvertToGLBoolean(fixedSampleLocations)));
1343*8975f5c5SAndroid Build Coastguard Worker }
1344*8975f5c5SAndroid Build Coastguard Worker
1345*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(
1346*8975f5c5SAndroid Build Coastguard Worker context, type, 0, 1,
1347*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texStorageFormat.internalFormat));
1348*8975f5c5SAndroid Build Coastguard Worker
1349*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1350*8975f5c5SAndroid Build Coastguard Worker }
1351*8975f5c5SAndroid Build Coastguard Worker
setStorageExternalMemory(const gl::Context * context,gl::TextureType type,size_t levels,GLenum internalFormat,const gl::Extents & size,gl::MemoryObject * memoryObject,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)1352*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setStorageExternalMemory(const gl::Context *context,
1353*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1354*8975f5c5SAndroid Build Coastguard Worker size_t levels,
1355*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1356*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &size,
1357*8975f5c5SAndroid Build Coastguard Worker gl::MemoryObject *memoryObject,
1358*8975f5c5SAndroid Build Coastguard Worker GLuint64 offset,
1359*8975f5c5SAndroid Build Coastguard Worker GLbitfield createFlags,
1360*8975f5c5SAndroid Build Coastguard Worker GLbitfield usageFlags,
1361*8975f5c5SAndroid Build Coastguard Worker const void *imageCreateInfoPNext)
1362*8975f5c5SAndroid Build Coastguard Worker {
1363*8975f5c5SAndroid Build Coastguard Worker // GL_ANGLE_external_objects_flags not supported.
1364*8975f5c5SAndroid Build Coastguard Worker ASSERT(createFlags == std::numeric_limits<uint32_t>::max());
1365*8975f5c5SAndroid Build Coastguard Worker ASSERT(usageFlags == std::numeric_limits<uint32_t>::max());
1366*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageCreateInfoPNext == nullptr);
1367*8975f5c5SAndroid Build Coastguard Worker
1368*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1369*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1370*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1371*8975f5c5SAndroid Build Coastguard Worker
1372*8975f5c5SAndroid Build Coastguard Worker MemoryObjectGL *memoryObjectGL = GetImplAs<MemoryObjectGL>(memoryObject);
1373*8975f5c5SAndroid Build Coastguard Worker
1374*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo =
1375*8975f5c5SAndroid Build Coastguard Worker gl::GetSizedInternalFormatInfo(internalFormat);
1376*8975f5c5SAndroid Build Coastguard Worker nativegl::TexStorageFormat texStorageFormat =
1377*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexStorageFormat(functions, features, internalFormat);
1378*8975f5c5SAndroid Build Coastguard Worker
1379*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1380*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
1381*8975f5c5SAndroid Build Coastguard Worker {
1382*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1383*8975f5c5SAndroid Build Coastguard Worker context,
1384*8975f5c5SAndroid Build Coastguard Worker functions->texStorageMem2DEXT(ToGLenum(type), static_cast<GLsizei>(levels),
1385*8975f5c5SAndroid Build Coastguard Worker texStorageFormat.internalFormat, size.width, size.height,
1386*8975f5c5SAndroid Build Coastguard Worker memoryObjectGL->getMemoryObjectID(), offset));
1387*8975f5c5SAndroid Build Coastguard Worker }
1388*8975f5c5SAndroid Build Coastguard Worker else
1389*8975f5c5SAndroid Build Coastguard Worker {
1390*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
1391*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1392*8975f5c5SAndroid Build Coastguard Worker context,
1393*8975f5c5SAndroid Build Coastguard Worker functions->texStorageMem3DEXT(ToGLenum(type), static_cast<GLsizei>(levels),
1394*8975f5c5SAndroid Build Coastguard Worker texStorageFormat.internalFormat, size.width, size.height,
1395*8975f5c5SAndroid Build Coastguard Worker size.depth, memoryObjectGL->getMemoryObjectID(), offset));
1396*8975f5c5SAndroid Build Coastguard Worker }
1397*8975f5c5SAndroid Build Coastguard Worker
1398*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(
1399*8975f5c5SAndroid Build Coastguard Worker context, type, 0, levels,
1400*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, texStorageFormat.internalFormat));
1401*8975f5c5SAndroid Build Coastguard Worker
1402*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1403*8975f5c5SAndroid Build Coastguard Worker }
1404*8975f5c5SAndroid Build Coastguard Worker
setImageExternal(const gl::Context * context,gl::TextureType type,egl::Stream * stream,const egl::Stream::GLTextureDescription & desc)1405*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setImageExternal(const gl::Context *context,
1406*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1407*8975f5c5SAndroid Build Coastguard Worker egl::Stream *stream,
1408*8975f5c5SAndroid Build Coastguard Worker const egl::Stream::GLTextureDescription &desc)
1409*8975f5c5SAndroid Build Coastguard Worker {
1410*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_UNREACHABLE(GetImplAs<ContextGL>(context));
1411*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Stop;
1412*8975f5c5SAndroid Build Coastguard Worker }
1413*8975f5c5SAndroid Build Coastguard Worker
generateMipmap(const gl::Context * context)1414*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::generateMipmap(const gl::Context *context)
1415*8975f5c5SAndroid Build Coastguard Worker {
1416*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
1417*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1418*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1419*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1420*8975f5c5SAndroid Build Coastguard Worker
1421*8975f5c5SAndroid Build Coastguard Worker const GLuint effectiveBaseLevel = mState.getEffectiveBaseLevel();
1422*8975f5c5SAndroid Build Coastguard Worker const GLuint maxLevel = mState.getMipmapMaxLevel();
1423*8975f5c5SAndroid Build Coastguard Worker
1424*8975f5c5SAndroid Build Coastguard Worker const gl::ImageDesc &baseLevelDesc = mState.getBaseLevelDesc();
1425*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &baseLevelInternalFormat = *baseLevelDesc.format.info;
1426*8975f5c5SAndroid Build Coastguard Worker
1427*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &baseLevelInfo = getBaseLevelInfo();
1428*8975f5c5SAndroid Build Coastguard Worker
1429*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1430*8975f5c5SAndroid Build Coastguard Worker if (getType() == gl::TextureType::_2D &&
1431*8975f5c5SAndroid Build Coastguard Worker ((baseLevelInternalFormat.colorEncoding == GL_SRGB &&
1432*8975f5c5SAndroid Build Coastguard Worker features.decodeEncodeSRGBForGenerateMipmap.enabled) ||
1433*8975f5c5SAndroid Build Coastguard Worker (features.useIntermediateTextureForGenerateMipmap.enabled &&
1434*8975f5c5SAndroid Build Coastguard Worker nativegl::SupportsNativeRendering(functions, mState.getType(),
1435*8975f5c5SAndroid Build Coastguard Worker baseLevelInfo.nativeInternalFormat))))
1436*8975f5c5SAndroid Build Coastguard Worker {
1437*8975f5c5SAndroid Build Coastguard Worker nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
1438*8975f5c5SAndroid Build Coastguard Worker functions, features, baseLevelInternalFormat.internalFormat,
1439*8975f5c5SAndroid Build Coastguard Worker baseLevelInternalFormat.format, baseLevelInternalFormat.type);
1440*8975f5c5SAndroid Build Coastguard Worker
1441*8975f5c5SAndroid Build Coastguard Worker // Manually allocate the mip levels of this texture if they don't exist
1442*8975f5c5SAndroid Build Coastguard Worker GLuint levelCount = maxLevel - effectiveBaseLevel + 1;
1443*8975f5c5SAndroid Build Coastguard Worker for (GLuint levelIdx = 1; levelIdx < levelCount; levelIdx++)
1444*8975f5c5SAndroid Build Coastguard Worker {
1445*8975f5c5SAndroid Build Coastguard Worker gl::Extents levelSize(std::max(baseLevelDesc.size.width >> levelIdx, 1),
1446*8975f5c5SAndroid Build Coastguard Worker std::max(baseLevelDesc.size.height >> levelIdx, 1), 1);
1447*8975f5c5SAndroid Build Coastguard Worker
1448*8975f5c5SAndroid Build Coastguard Worker const gl::ImageDesc &levelDesc =
1449*8975f5c5SAndroid Build Coastguard Worker mState.getImageDesc(gl::TextureTarget::_2D, effectiveBaseLevel + levelIdx);
1450*8975f5c5SAndroid Build Coastguard Worker
1451*8975f5c5SAndroid Build Coastguard Worker if (levelDesc.size != levelSize || *levelDesc.format.info != baseLevelInternalFormat)
1452*8975f5c5SAndroid Build Coastguard Worker {
1453*8975f5c5SAndroid Build Coastguard Worker // Make sure no pixel unpack buffer is bound
1454*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
1455*8975f5c5SAndroid Build Coastguard Worker
1456*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(
1457*8975f5c5SAndroid Build Coastguard Worker context, functions->texImage2D(
1458*8975f5c5SAndroid Build Coastguard Worker ToGLenum(getType()), effectiveBaseLevel + levelIdx,
1459*8975f5c5SAndroid Build Coastguard Worker texImageFormat.internalFormat, levelSize.width, levelSize.height,
1460*8975f5c5SAndroid Build Coastguard Worker 0, texImageFormat.format, texImageFormat.type, nullptr));
1461*8975f5c5SAndroid Build Coastguard Worker }
1462*8975f5c5SAndroid Build Coastguard Worker }
1463*8975f5c5SAndroid Build Coastguard Worker
1464*8975f5c5SAndroid Build Coastguard Worker // Use the blitter to generate the mips
1465*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
1466*8975f5c5SAndroid Build Coastguard Worker if (baseLevelInternalFormat.colorEncoding == GL_SRGB)
1467*8975f5c5SAndroid Build Coastguard Worker {
1468*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->generateSRGBMipmap(context, this, effectiveBaseLevel, levelCount,
1469*8975f5c5SAndroid Build Coastguard Worker baseLevelDesc.size));
1470*8975f5c5SAndroid Build Coastguard Worker }
1471*8975f5c5SAndroid Build Coastguard Worker else
1472*8975f5c5SAndroid Build Coastguard Worker {
1473*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->generateMipmap(context, this, effectiveBaseLevel, levelCount,
1474*8975f5c5SAndroid Build Coastguard Worker baseLevelDesc.size, texImageFormat));
1475*8975f5c5SAndroid Build Coastguard Worker }
1476*8975f5c5SAndroid Build Coastguard Worker }
1477*8975f5c5SAndroid Build Coastguard Worker else
1478*8975f5c5SAndroid Build Coastguard Worker {
1479*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY_ALWAYS_CHECK(context, functions->generateMipmap(ToGLenum(getType())));
1480*8975f5c5SAndroid Build Coastguard Worker }
1481*8975f5c5SAndroid Build Coastguard Worker
1482*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, getType(), effectiveBaseLevel, maxLevel - effectiveBaseLevel,
1483*8975f5c5SAndroid Build Coastguard Worker getBaseLevelInfo());
1484*8975f5c5SAndroid Build Coastguard Worker
1485*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1486*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1487*8975f5c5SAndroid Build Coastguard Worker }
1488*8975f5c5SAndroid Build Coastguard Worker
clearImage(const gl::Context * context,GLint level,GLenum format,GLenum type,const uint8_t * data)1489*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::clearImage(const gl::Context *context,
1490*8975f5c5SAndroid Build Coastguard Worker GLint level,
1491*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1492*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1493*8975f5c5SAndroid Build Coastguard Worker const uint8_t *data)
1494*8975f5c5SAndroid Build Coastguard Worker {
1495*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
1496*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1497*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1498*8975f5c5SAndroid Build Coastguard Worker
1499*8975f5c5SAndroid Build Coastguard Worker nativegl::TexSubImageFormat texSubImageFormat =
1500*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexSubImageFormat(functions, features, format, type);
1501*8975f5c5SAndroid Build Coastguard Worker
1502*8975f5c5SAndroid Build Coastguard Worker // Some drivers may use color mask state when clearing textures.
1503*8975f5c5SAndroid Build Coastguard Worker contextGL->getStateManager()->setColorMask(true, true, true, true);
1504*8975f5c5SAndroid Build Coastguard Worker
1505*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->clearTexImage(mTextureID, level, texSubImageFormat.format,
1506*8975f5c5SAndroid Build Coastguard Worker texSubImageFormat.type, data));
1507*8975f5c5SAndroid Build Coastguard Worker
1508*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1509*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1510*8975f5c5SAndroid Build Coastguard Worker }
1511*8975f5c5SAndroid Build Coastguard Worker
clearSubImage(const gl::Context * context,GLint level,const gl::Box & area,GLenum format,GLenum type,const uint8_t * data)1512*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::clearSubImage(const gl::Context *context,
1513*8975f5c5SAndroid Build Coastguard Worker GLint level,
1514*8975f5c5SAndroid Build Coastguard Worker const gl::Box &area,
1515*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1516*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1517*8975f5c5SAndroid Build Coastguard Worker const uint8_t *data)
1518*8975f5c5SAndroid Build Coastguard Worker {
1519*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
1520*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1521*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1522*8975f5c5SAndroid Build Coastguard Worker
1523*8975f5c5SAndroid Build Coastguard Worker // Some drivers may use color mask state when clearing textures.
1524*8975f5c5SAndroid Build Coastguard Worker contextGL->getStateManager()->setColorMask(true, true, true, true);
1525*8975f5c5SAndroid Build Coastguard Worker
1526*8975f5c5SAndroid Build Coastguard Worker nativegl::TexSubImageFormat texSubImageFormat =
1527*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTexSubImageFormat(functions, features, format, type);
1528*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->clearTexSubImage(
1529*8975f5c5SAndroid Build Coastguard Worker mTextureID, level, area.x, area.y, area.z, area.width, area.height,
1530*8975f5c5SAndroid Build Coastguard Worker area.depth, texSubImageFormat.format, texSubImageFormat.type, data));
1531*8975f5c5SAndroid Build Coastguard Worker
1532*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
1533*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1534*8975f5c5SAndroid Build Coastguard Worker }
1535*8975f5c5SAndroid Build Coastguard Worker
bindTexImage(const gl::Context * context,egl::Surface * surface)1536*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::bindTexImage(const gl::Context *context, egl::Surface *surface)
1537*8975f5c5SAndroid Build Coastguard Worker {
1538*8975f5c5SAndroid Build Coastguard Worker ASSERT(getType() == gl::TextureType::_2D || getType() == gl::TextureType::Rectangle);
1539*8975f5c5SAndroid Build Coastguard Worker
1540*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1541*8975f5c5SAndroid Build Coastguard Worker
1542*8975f5c5SAndroid Build Coastguard Worker // Make sure this texture is bound
1543*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1544*8975f5c5SAndroid Build Coastguard Worker
1545*8975f5c5SAndroid Build Coastguard Worker SurfaceGL *surfaceGL = GetImplAs<SurfaceGL>(surface);
1546*8975f5c5SAndroid Build Coastguard Worker
1547*8975f5c5SAndroid Build Coastguard Worker const gl::Format &surfaceFormat = surface->getBindTexImageFormat();
1548*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, getType(), 0, 1,
1549*8975f5c5SAndroid Build Coastguard Worker LevelInfoGL(surfaceFormat.info->format, surfaceFormat.info->internalFormat, false,
1550*8975f5c5SAndroid Build Coastguard Worker LUMAWorkaroundGL(), surfaceGL->hasEmulatedAlphaChannel()));
1551*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1552*8975f5c5SAndroid Build Coastguard Worker }
1553*8975f5c5SAndroid Build Coastguard Worker
releaseTexImage(const gl::Context * context)1554*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::releaseTexImage(const gl::Context *context)
1555*8975f5c5SAndroid Build Coastguard Worker {
1556*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(recreateTexture(context));
1557*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1558*8975f5c5SAndroid Build Coastguard Worker }
1559*8975f5c5SAndroid Build Coastguard Worker
setEGLImageTarget(const gl::Context * context,gl::TextureType type,egl::Image * image)1560*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setEGLImageTarget(const gl::Context *context,
1561*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
1562*8975f5c5SAndroid Build Coastguard Worker egl::Image *image)
1563*8975f5c5SAndroid Build Coastguard Worker {
1564*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
1565*8975f5c5SAndroid Build Coastguard Worker
1566*8975f5c5SAndroid Build Coastguard Worker ImageGL *imageGL = GetImplAs<ImageGL>(image);
1567*8975f5c5SAndroid Build Coastguard Worker
1568*8975f5c5SAndroid Build Coastguard Worker GLenum imageNativeInternalFormat = GL_NONE;
1569*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat));
1570*8975f5c5SAndroid Build Coastguard Worker
1571*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &originalInternalFormatInfo = *image->getFormat().info;
1572*8975f5c5SAndroid Build Coastguard Worker
1573*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, type, 0, 1,
1574*8975f5c5SAndroid Build Coastguard Worker GetLevelInfo(features, originalInternalFormatInfo, imageNativeInternalFormat));
1575*8975f5c5SAndroid Build Coastguard Worker
1576*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1577*8975f5c5SAndroid Build Coastguard Worker }
1578*8975f5c5SAndroid Build Coastguard Worker
getNativeID() const1579*8975f5c5SAndroid Build Coastguard Worker GLint TextureGL::getNativeID() const
1580*8975f5c5SAndroid Build Coastguard Worker {
1581*8975f5c5SAndroid Build Coastguard Worker return mTextureID;
1582*8975f5c5SAndroid Build Coastguard Worker }
1583*8975f5c5SAndroid Build Coastguard Worker
syncState(const gl::Context * context,const gl::Texture::DirtyBits & dirtyBits,gl::Command source)1584*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::syncState(const gl::Context *context,
1585*8975f5c5SAndroid Build Coastguard Worker const gl::Texture::DirtyBits &dirtyBits,
1586*8975f5c5SAndroid Build Coastguard Worker gl::Command source)
1587*8975f5c5SAndroid Build Coastguard Worker {
1588*8975f5c5SAndroid Build Coastguard Worker if (dirtyBits.none() && mLocalDirtyBits.none())
1589*8975f5c5SAndroid Build Coastguard Worker {
1590*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1591*8975f5c5SAndroid Build Coastguard Worker }
1592*8975f5c5SAndroid Build Coastguard Worker
1593*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1594*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1595*8975f5c5SAndroid Build Coastguard Worker
1596*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1597*8975f5c5SAndroid Build Coastguard Worker
1598*8975f5c5SAndroid Build Coastguard Worker gl::Texture::DirtyBits syncDirtyBits = dirtyBits | mLocalDirtyBits;
1599*8975f5c5SAndroid Build Coastguard Worker if (dirtyBits[gl::Texture::DIRTY_BIT_BASE_LEVEL] || dirtyBits[gl::Texture::DIRTY_BIT_MAX_LEVEL])
1600*8975f5c5SAndroid Build Coastguard Worker {
1601*8975f5c5SAndroid Build Coastguard Worker // Don't know if the previous base level was using any workarounds, always re-sync the
1602*8975f5c5SAndroid Build Coastguard Worker // workaround dirty bits
1603*8975f5c5SAndroid Build Coastguard Worker syncDirtyBits |= GetLevelWorkaroundDirtyBits();
1604*8975f5c5SAndroid Build Coastguard Worker
1605*8975f5c5SAndroid Build Coastguard Worker // If the base level format has changed, depth stencil texture mode may need to be updated
1606*8975f5c5SAndroid Build Coastguard Worker if (!mState.getImmutableFormat() && (context->getClientVersion() >= gl::ES_3_1 ||
1607*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().stencilTexturingANGLE))
1608*8975f5c5SAndroid Build Coastguard Worker {
1609*8975f5c5SAndroid Build Coastguard Worker syncDirtyBits.set(gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
1610*8975f5c5SAndroid Build Coastguard Worker }
1611*8975f5c5SAndroid Build Coastguard Worker
1612*8975f5c5SAndroid Build Coastguard Worker // If the base level format has changed, border color may need to be updated
1613*8975f5c5SAndroid Build Coastguard Worker if (!mState.getImmutableFormat() && (context->getClientVersion() >= gl::ES_3_2 ||
1614*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureBorderClampAny()))
1615*8975f5c5SAndroid Build Coastguard Worker {
1616*8975f5c5SAndroid Build Coastguard Worker syncDirtyBits.set(gl::Texture::DIRTY_BIT_BORDER_COLOR);
1617*8975f5c5SAndroid Build Coastguard Worker }
1618*8975f5c5SAndroid Build Coastguard Worker }
1619*8975f5c5SAndroid Build Coastguard Worker for (auto dirtyBit : syncDirtyBits)
1620*8975f5c5SAndroid Build Coastguard Worker {
1621*8975f5c5SAndroid Build Coastguard Worker
1622*8975f5c5SAndroid Build Coastguard Worker switch (dirtyBit)
1623*8975f5c5SAndroid Build Coastguard Worker {
1624*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MIN_FILTER:
1625*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMinFilter(mState.getSamplerState().getMinFilter()))
1626*8975f5c5SAndroid Build Coastguard Worker {
1627*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1628*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(
1629*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1630*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MIN_FILTER, mAppliedSampler.getMinFilter()));
1631*8975f5c5SAndroid Build Coastguard Worker }
1632*8975f5c5SAndroid Build Coastguard Worker break;
1633*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MAG_FILTER:
1634*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMagFilter(mState.getSamplerState().getMagFilter()))
1635*8975f5c5SAndroid Build Coastguard Worker {
1636*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1637*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(
1638*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1639*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MAG_FILTER, mAppliedSampler.getMagFilter()));
1640*8975f5c5SAndroid Build Coastguard Worker }
1641*8975f5c5SAndroid Build Coastguard Worker break;
1642*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_WRAP_S:
1643*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setWrapS(mState.getSamplerState().getWrapS()))
1644*8975f5c5SAndroid Build Coastguard Worker {
1645*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1646*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1647*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_WRAP_S, mAppliedSampler.getWrapS()));
1648*8975f5c5SAndroid Build Coastguard Worker }
1649*8975f5c5SAndroid Build Coastguard Worker break;
1650*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_WRAP_T:
1651*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setWrapT(mState.getSamplerState().getWrapT()))
1652*8975f5c5SAndroid Build Coastguard Worker {
1653*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1654*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1655*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_WRAP_T, mAppliedSampler.getWrapT()));
1656*8975f5c5SAndroid Build Coastguard Worker }
1657*8975f5c5SAndroid Build Coastguard Worker break;
1658*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_WRAP_R:
1659*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setWrapR(mState.getSamplerState().getWrapR()))
1660*8975f5c5SAndroid Build Coastguard Worker {
1661*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1662*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1663*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_WRAP_R, mAppliedSampler.getWrapR()));
1664*8975f5c5SAndroid Build Coastguard Worker }
1665*8975f5c5SAndroid Build Coastguard Worker break;
1666*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MAX_ANISOTROPY:
1667*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMaxAnisotropy(mState.getSamplerState().getMaxAnisotropy()))
1668*8975f5c5SAndroid Build Coastguard Worker {
1669*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameterf(
1670*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1671*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MAX_ANISOTROPY_EXT,
1672*8975f5c5SAndroid Build Coastguard Worker mAppliedSampler.getMaxAnisotropy()));
1673*8975f5c5SAndroid Build Coastguard Worker }
1674*8975f5c5SAndroid Build Coastguard Worker break;
1675*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MIN_LOD:
1676*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMinLod(mState.getSamplerState().getMinLod()))
1677*8975f5c5SAndroid Build Coastguard Worker {
1678*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameterf(
1679*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1680*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MIN_LOD, mAppliedSampler.getMinLod()));
1681*8975f5c5SAndroid Build Coastguard Worker }
1682*8975f5c5SAndroid Build Coastguard Worker break;
1683*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MAX_LOD:
1684*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMaxLod(mState.getSamplerState().getMaxLod()))
1685*8975f5c5SAndroid Build Coastguard Worker {
1686*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameterf(
1687*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1688*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MAX_LOD, mAppliedSampler.getMaxLod()));
1689*8975f5c5SAndroid Build Coastguard Worker }
1690*8975f5c5SAndroid Build Coastguard Worker break;
1691*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_COMPARE_MODE:
1692*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setCompareMode(mState.getSamplerState().getCompareMode()))
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1695*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(
1696*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1697*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_COMPARE_MODE, mAppliedSampler.getCompareMode()));
1698*8975f5c5SAndroid Build Coastguard Worker }
1699*8975f5c5SAndroid Build Coastguard Worker break;
1700*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_COMPARE_FUNC:
1701*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setCompareFunc(mState.getSamplerState().getCompareFunc()))
1702*8975f5c5SAndroid Build Coastguard Worker {
1703*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1704*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(
1705*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1706*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_COMPARE_FUNC, mAppliedSampler.getCompareFunc()));
1707*8975f5c5SAndroid Build Coastguard Worker }
1708*8975f5c5SAndroid Build Coastguard Worker break;
1709*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_SRGB_DECODE:
1710*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setSRGBDecode(mState.getSamplerState().getSRGBDecode()))
1711*8975f5c5SAndroid Build Coastguard Worker {
1712*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1713*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(
1714*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1715*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SRGB_DECODE_EXT, mAppliedSampler.getSRGBDecode()));
1716*8975f5c5SAndroid Build Coastguard Worker }
1717*8975f5c5SAndroid Build Coastguard Worker break;
1718*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_BORDER_COLOR:
1719*8975f5c5SAndroid Build Coastguard Worker {
1720*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &levelInfo = getBaseLevelInfo();
1721*8975f5c5SAndroid Build Coastguard Worker angle::ColorGeneric borderColor = mState.getSamplerState().getBorderColor();
1722*8975f5c5SAndroid Build Coastguard Worker // Formats that have workarounds must be present in FormatHasBorderColorWorkarounds.
1723*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.sourceFormat == GL_ALPHA)
1724*8975f5c5SAndroid Build Coastguard Worker {
1725*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.lumaWorkaround.enabled)
1726*8975f5c5SAndroid Build Coastguard Worker {
1727*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED);
1728*8975f5c5SAndroid Build Coastguard Worker borderColor.colorF.red = borderColor.colorF.alpha;
1729*8975f5c5SAndroid Build Coastguard Worker }
1730*8975f5c5SAndroid Build Coastguard Worker else
1731*8975f5c5SAndroid Build Coastguard Worker {
1732*8975f5c5SAndroid Build Coastguard Worker // Some ES drivers treat ALPHA as swizzled RG, triplicating
1733*8975f5c5SAndroid Build Coastguard Worker // border's red to RGB and sampling border's green as alpha.
1734*8975f5c5SAndroid Build Coastguard Worker borderColor.colorF.red = 0.0f;
1735*8975f5c5SAndroid Build Coastguard Worker borderColor.colorF.green = borderColor.colorF.alpha;
1736*8975f5c5SAndroid Build Coastguard Worker }
1737*8975f5c5SAndroid Build Coastguard Worker }
1738*8975f5c5SAndroid Build Coastguard Worker else if (levelInfo.sourceFormat == GL_LUMINANCE_ALPHA)
1739*8975f5c5SAndroid Build Coastguard Worker {
1740*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.lumaWorkaround.enabled)
1741*8975f5c5SAndroid Build Coastguard Worker {
1742*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RG);
1743*8975f5c5SAndroid Build Coastguard Worker }
1744*8975f5c5SAndroid Build Coastguard Worker // When using desktop GL, this format is emulated as swizzled RG.
1745*8975f5c5SAndroid Build Coastguard Worker // Some ES drivers do the same without adjusting the border color.
1746*8975f5c5SAndroid Build Coastguard Worker borderColor.colorF.green = borderColor.colorF.alpha;
1747*8975f5c5SAndroid Build Coastguard Worker }
1748*8975f5c5SAndroid Build Coastguard Worker
1749*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setBorderColor(borderColor))
1750*8975f5c5SAndroid Build Coastguard Worker {
1751*8975f5c5SAndroid Build Coastguard Worker switch (borderColor.type)
1752*8975f5c5SAndroid Build Coastguard Worker {
1753*8975f5c5SAndroid Build Coastguard Worker case angle::ColorGeneric::Type::Float:
1754*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1755*8975f5c5SAndroid Build Coastguard Worker functions->texParameterfv(
1756*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1757*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_BORDER_COLOR, &borderColor.colorF.red));
1758*8975f5c5SAndroid Build Coastguard Worker break;
1759*8975f5c5SAndroid Build Coastguard Worker case angle::ColorGeneric::Type::Int:
1760*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1761*8975f5c5SAndroid Build Coastguard Worker functions->texParameterIiv(
1762*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1763*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_BORDER_COLOR, &borderColor.colorI.red));
1764*8975f5c5SAndroid Build Coastguard Worker break;
1765*8975f5c5SAndroid Build Coastguard Worker case angle::ColorGeneric::Type::UInt:
1766*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1767*8975f5c5SAndroid Build Coastguard Worker functions->texParameterIuiv(
1768*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1769*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_BORDER_COLOR, &borderColor.colorUI.red));
1770*8975f5c5SAndroid Build Coastguard Worker break;
1771*8975f5c5SAndroid Build Coastguard Worker default:
1772*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1773*8975f5c5SAndroid Build Coastguard Worker break;
1774*8975f5c5SAndroid Build Coastguard Worker }
1775*8975f5c5SAndroid Build Coastguard Worker }
1776*8975f5c5SAndroid Build Coastguard Worker break;
1777*8975f5c5SAndroid Build Coastguard Worker }
1778*8975f5c5SAndroid Build Coastguard Worker
1779*8975f5c5SAndroid Build Coastguard Worker // Texture state
1780*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_SWIZZLE_RED:
1781*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_R,
1782*8975f5c5SAndroid Build Coastguard Worker mState.getSwizzleState().swizzleRed,
1783*8975f5c5SAndroid Build Coastguard Worker &mAppliedSwizzle.swizzleRed));
1784*8975f5c5SAndroid Build Coastguard Worker break;
1785*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN:
1786*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_G,
1787*8975f5c5SAndroid Build Coastguard Worker mState.getSwizzleState().swizzleGreen,
1788*8975f5c5SAndroid Build Coastguard Worker &mAppliedSwizzle.swizzleGreen));
1789*8975f5c5SAndroid Build Coastguard Worker break;
1790*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE:
1791*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_B,
1792*8975f5c5SAndroid Build Coastguard Worker mState.getSwizzleState().swizzleBlue,
1793*8975f5c5SAndroid Build Coastguard Worker &mAppliedSwizzle.swizzleBlue));
1794*8975f5c5SAndroid Build Coastguard Worker break;
1795*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA:
1796*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(syncTextureStateSwizzle(context, functions, GL_TEXTURE_SWIZZLE_A,
1797*8975f5c5SAndroid Build Coastguard Worker mState.getSwizzleState().swizzleAlpha,
1798*8975f5c5SAndroid Build Coastguard Worker &mAppliedSwizzle.swizzleAlpha));
1799*8975f5c5SAndroid Build Coastguard Worker break;
1800*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_BASE_LEVEL:
1801*8975f5c5SAndroid Build Coastguard Worker if (mAppliedBaseLevel != mState.getEffectiveBaseLevel())
1802*8975f5c5SAndroid Build Coastguard Worker {
1803*8975f5c5SAndroid Build Coastguard Worker mAppliedBaseLevel = mState.getEffectiveBaseLevel();
1804*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1805*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1806*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_BASE_LEVEL, mAppliedBaseLevel));
1807*8975f5c5SAndroid Build Coastguard Worker }
1808*8975f5c5SAndroid Build Coastguard Worker break;
1809*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_MAX_LEVEL:
1810*8975f5c5SAndroid Build Coastguard Worker if (mAppliedMaxLevel != mState.getEffectiveMaxLevel())
1811*8975f5c5SAndroid Build Coastguard Worker {
1812*8975f5c5SAndroid Build Coastguard Worker mAppliedMaxLevel = mState.getEffectiveMaxLevel();
1813*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1814*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1815*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_MAX_LEVEL, mAppliedMaxLevel));
1816*8975f5c5SAndroid Build Coastguard Worker }
1817*8975f5c5SAndroid Build Coastguard Worker break;
1818*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE:
1819*8975f5c5SAndroid Build Coastguard Worker {
1820*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getClientVersion() >= gl::ES_3_1 ||
1821*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().stencilTexturingANGLE);
1822*8975f5c5SAndroid Build Coastguard Worker
1823*8975f5c5SAndroid Build Coastguard Worker // The DEPTH_STENCIL_TEXTURE_MODE state must affect only
1824*8975f5c5SAndroid Build Coastguard Worker // DEPTH_STENCIL textures (OpenGL ES 3.2, Section 8.16).
1825*8975f5c5SAndroid Build Coastguard Worker // Some drivers do not follow this rule and exhibit various side effects
1826*8975f5c5SAndroid Build Coastguard Worker // when this mode is set to STENCIL_INDEX for textures of other formats.
1827*8975f5c5SAndroid Build Coastguard Worker const GLenum mode = (getBaseLevelInfo().sourceFormat != GL_DEPTH_STENCIL)
1828*8975f5c5SAndroid Build Coastguard Worker ? GL_DEPTH_COMPONENT
1829*8975f5c5SAndroid Build Coastguard Worker : mState.getDepthStencilTextureMode();
1830*8975f5c5SAndroid Build Coastguard Worker
1831*8975f5c5SAndroid Build Coastguard Worker if (mAppliedDepthStencilTextureMode != mode)
1832*8975f5c5SAndroid Build Coastguard Worker {
1833*8975f5c5SAndroid Build Coastguard Worker mAppliedDepthStencilTextureMode = mode;
1834*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(
1835*8975f5c5SAndroid Build Coastguard Worker nativegl::GetTextureBindingTarget(getType()),
1836*8975f5c5SAndroid Build Coastguard Worker GL_DEPTH_STENCIL_TEXTURE_MODE, mode));
1837*8975f5c5SAndroid Build Coastguard Worker }
1838*8975f5c5SAndroid Build Coastguard Worker break;
1839*8975f5c5SAndroid Build Coastguard Worker }
1840*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_USAGE:
1841*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_RENDERABILITY_VALIDATION_ANGLE:
1842*8975f5c5SAndroid Build Coastguard Worker break;
1843*8975f5c5SAndroid Build Coastguard Worker
1844*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_IMPLEMENTATION:
1845*8975f5c5SAndroid Build Coastguard Worker // This special dirty bit is used to signal the front-end that the implementation
1846*8975f5c5SAndroid Build Coastguard Worker // has local dirty bits. The real dirty bits are in mLocalDirty bits.
1847*8975f5c5SAndroid Build Coastguard Worker break;
1848*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_BOUND_AS_IMAGE:
1849*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_BOUND_AS_ATTACHMENT:
1850*8975f5c5SAndroid Build Coastguard Worker case gl::Texture::DIRTY_BIT_BOUND_TO_MSRTT_FRAMEBUFFER:
1851*8975f5c5SAndroid Build Coastguard Worker // Only used for Vulkan.
1852*8975f5c5SAndroid Build Coastguard Worker break;
1853*8975f5c5SAndroid Build Coastguard Worker
1854*8975f5c5SAndroid Build Coastguard Worker default:
1855*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1856*8975f5c5SAndroid Build Coastguard Worker }
1857*8975f5c5SAndroid Build Coastguard Worker }
1858*8975f5c5SAndroid Build Coastguard Worker
1859*8975f5c5SAndroid Build Coastguard Worker mAllModifiedDirtyBits |= syncDirtyBits;
1860*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.reset();
1861*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1862*8975f5c5SAndroid Build Coastguard Worker }
1863*8975f5c5SAndroid Build Coastguard Worker
hasAnyDirtyBit() const1864*8975f5c5SAndroid Build Coastguard Worker bool TextureGL::hasAnyDirtyBit() const
1865*8975f5c5SAndroid Build Coastguard Worker {
1866*8975f5c5SAndroid Build Coastguard Worker return mLocalDirtyBits.any();
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker
setBaseLevel(const gl::Context * context,GLuint baseLevel)1869*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setBaseLevel(const gl::Context *context, GLuint baseLevel)
1870*8975f5c5SAndroid Build Coastguard Worker {
1871*8975f5c5SAndroid Build Coastguard Worker if (baseLevel != mAppliedBaseLevel)
1872*8975f5c5SAndroid Build Coastguard Worker {
1873*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1874*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1875*8975f5c5SAndroid Build Coastguard Worker
1876*8975f5c5SAndroid Build Coastguard Worker mAppliedBaseLevel = baseLevel;
1877*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_BASE_LEVEL);
1878*8975f5c5SAndroid Build Coastguard Worker
1879*8975f5c5SAndroid Build Coastguard Worker // Signal to the GL layer that the Impl has dirty bits.
1880*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1881*8975f5c5SAndroid Build Coastguard Worker
1882*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1883*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_BASE_LEVEL,
1884*8975f5c5SAndroid Build Coastguard Worker baseLevel));
1885*8975f5c5SAndroid Build Coastguard Worker }
1886*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1887*8975f5c5SAndroid Build Coastguard Worker }
1888*8975f5c5SAndroid Build Coastguard Worker
setMaxLevel(const gl::Context * context,GLuint maxLevel)1889*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setMaxLevel(const gl::Context *context, GLuint maxLevel)
1890*8975f5c5SAndroid Build Coastguard Worker {
1891*8975f5c5SAndroid Build Coastguard Worker if (maxLevel != mAppliedMaxLevel)
1892*8975f5c5SAndroid Build Coastguard Worker {
1893*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1894*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1895*8975f5c5SAndroid Build Coastguard Worker
1896*8975f5c5SAndroid Build Coastguard Worker mAppliedMaxLevel = maxLevel;
1897*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MAX_LEVEL);
1898*8975f5c5SAndroid Build Coastguard Worker
1899*8975f5c5SAndroid Build Coastguard Worker // Signal to the GL layer that the Impl has dirty bits.
1900*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1901*8975f5c5SAndroid Build Coastguard Worker
1902*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1903*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1904*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAX_LEVEL, maxLevel));
1905*8975f5c5SAndroid Build Coastguard Worker }
1906*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1907*8975f5c5SAndroid Build Coastguard Worker }
1908*8975f5c5SAndroid Build Coastguard Worker
setMinFilter(const gl::Context * context,GLenum filter)1909*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setMinFilter(const gl::Context *context, GLenum filter)
1910*8975f5c5SAndroid Build Coastguard Worker {
1911*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMinFilter(filter))
1912*8975f5c5SAndroid Build Coastguard Worker {
1913*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1914*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1915*8975f5c5SAndroid Build Coastguard Worker
1916*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MIN_FILTER);
1917*8975f5c5SAndroid Build Coastguard Worker
1918*8975f5c5SAndroid Build Coastguard Worker // Signal to the GL layer that the Impl has dirty bits.
1919*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1920*8975f5c5SAndroid Build Coastguard Worker
1921*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1922*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1923*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MIN_FILTER, filter));
1924*8975f5c5SAndroid Build Coastguard Worker }
1925*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1926*8975f5c5SAndroid Build Coastguard Worker }
setMagFilter(const gl::Context * context,GLenum filter)1927*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setMagFilter(const gl::Context *context, GLenum filter)
1928*8975f5c5SAndroid Build Coastguard Worker {
1929*8975f5c5SAndroid Build Coastguard Worker if (mAppliedSampler.setMagFilter(filter))
1930*8975f5c5SAndroid Build Coastguard Worker {
1931*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1932*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1933*8975f5c5SAndroid Build Coastguard Worker
1934*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_MAG_FILTER);
1935*8975f5c5SAndroid Build Coastguard Worker
1936*8975f5c5SAndroid Build Coastguard Worker // Signal to the GL layer that the Impl has dirty bits.
1937*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1938*8975f5c5SAndroid Build Coastguard Worker
1939*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1940*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
1941*8975f5c5SAndroid Build Coastguard Worker functions->texParameteri(ToGLenum(getType()), GL_TEXTURE_MAG_FILTER, filter));
1942*8975f5c5SAndroid Build Coastguard Worker }
1943*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1944*8975f5c5SAndroid Build Coastguard Worker }
1945*8975f5c5SAndroid Build Coastguard Worker
setSwizzle(const gl::Context * context,GLint swizzle[4])1946*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4])
1947*8975f5c5SAndroid Build Coastguard Worker {
1948*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState resultingSwizzle =
1949*8975f5c5SAndroid Build Coastguard Worker gl::SwizzleState(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
1950*8975f5c5SAndroid Build Coastguard Worker
1951*8975f5c5SAndroid Build Coastguard Worker if (resultingSwizzle != mAppliedSwizzle)
1952*8975f5c5SAndroid Build Coastguard Worker {
1953*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1954*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
1955*8975f5c5SAndroid Build Coastguard Worker
1956*8975f5c5SAndroid Build Coastguard Worker mAppliedSwizzle = resultingSwizzle;
1957*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_RED);
1958*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_GREEN);
1959*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_BLUE);
1960*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA);
1961*8975f5c5SAndroid Build Coastguard Worker
1962*8975f5c5SAndroid Build Coastguard Worker // Signal to the GL layer that the Impl has dirty bits.
1963*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
1964*8975f5c5SAndroid Build Coastguard Worker
1965*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
1966*8975f5c5SAndroid Build Coastguard Worker if (functions->standard == STANDARD_GL_ES)
1967*8975f5c5SAndroid Build Coastguard Worker {
1968*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
1969*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SWIZZLE_R, swizzle[0]));
1970*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
1971*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SWIZZLE_G, swizzle[1]));
1972*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
1973*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SWIZZLE_B, swizzle[2]));
1974*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()),
1975*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SWIZZLE_A, swizzle[3]));
1976*8975f5c5SAndroid Build Coastguard Worker }
1977*8975f5c5SAndroid Build Coastguard Worker else
1978*8975f5c5SAndroid Build Coastguard Worker {
1979*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteriv(ToGLenum(getType()),
1980*8975f5c5SAndroid Build Coastguard Worker GL_TEXTURE_SWIZZLE_RGBA, swizzle));
1981*8975f5c5SAndroid Build Coastguard Worker }
1982*8975f5c5SAndroid Build Coastguard Worker }
1983*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
1984*8975f5c5SAndroid Build Coastguard Worker }
1985*8975f5c5SAndroid Build Coastguard Worker
setBuffer(const gl::Context * context,GLenum internalFormat)1986*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::setBuffer(const gl::Context *context, GLenum internalFormat)
1987*8975f5c5SAndroid Build Coastguard Worker {
1988*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
1989*8975f5c5SAndroid Build Coastguard Worker const gl::OffsetBindingPointer<gl::Buffer> &bufferBinding = mState.getBuffer();
1990*8975f5c5SAndroid Build Coastguard Worker const gl::Buffer *buffer = bufferBinding.get();
1991*8975f5c5SAndroid Build Coastguard Worker const GLintptr offset = bufferBinding.getOffset();
1992*8975f5c5SAndroid Build Coastguard Worker const GLsizeiptr size = bufferBinding.getSize();
1993*8975f5c5SAndroid Build Coastguard Worker const GLuint bufferID = buffer ? GetImplAs<BufferGL>(buffer)->getBufferID() : 0;
1994*8975f5c5SAndroid Build Coastguard Worker
1995*8975f5c5SAndroid Build Coastguard Worker // If buffer is not bound, use texBuffer to unbind it. If size is 0, texBuffer was used to
1996*8975f5c5SAndroid Build Coastguard Worker // create this binding, so use the same function. This will allow the implementation to take
1997*8975f5c5SAndroid Build Coastguard Worker // the current size of the buffer on every draw/dispatch call even if the buffer size changes.
1998*8975f5c5SAndroid Build Coastguard Worker if (buffer == nullptr || size == 0)
1999*8975f5c5SAndroid Build Coastguard Worker {
2000*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texBuffer(GL_TEXTURE_BUFFER, internalFormat, bufferID));
2001*8975f5c5SAndroid Build Coastguard Worker }
2002*8975f5c5SAndroid Build Coastguard Worker else
2003*8975f5c5SAndroid Build Coastguard Worker {
2004*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
2005*8975f5c5SAndroid Build Coastguard Worker functions->texBufferRange(GL_TEXTURE_BUFFER, internalFormat, bufferID, offset,
2006*8975f5c5SAndroid Build Coastguard Worker GetBoundBufferAvailableSize(bufferBinding)));
2007*8975f5c5SAndroid Build Coastguard Worker }
2008*8975f5c5SAndroid Build Coastguard Worker
2009*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2010*8975f5c5SAndroid Build Coastguard Worker }
2011*8975f5c5SAndroid Build Coastguard Worker
getNativeInternalFormat(const gl::ImageIndex & index) const2012*8975f5c5SAndroid Build Coastguard Worker GLenum TextureGL::getNativeInternalFormat(const gl::ImageIndex &index) const
2013*8975f5c5SAndroid Build Coastguard Worker {
2014*8975f5c5SAndroid Build Coastguard Worker return getLevelInfo(index.getTarget(), index.getLevelIndex()).nativeInternalFormat;
2015*8975f5c5SAndroid Build Coastguard Worker }
2016*8975f5c5SAndroid Build Coastguard Worker
hasEmulatedAlphaChannel(const gl::ImageIndex & index) const2017*8975f5c5SAndroid Build Coastguard Worker bool TextureGL::hasEmulatedAlphaChannel(const gl::ImageIndex &index) const
2018*8975f5c5SAndroid Build Coastguard Worker {
2019*8975f5c5SAndroid Build Coastguard Worker return getLevelInfo(index.getTargetOrFirstCubeFace(), index.getLevelIndex())
2020*8975f5c5SAndroid Build Coastguard Worker .emulatedAlphaChannel;
2021*8975f5c5SAndroid Build Coastguard Worker }
2022*8975f5c5SAndroid Build Coastguard Worker
recreateTexture(const gl::Context * context)2023*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::recreateTexture(const gl::Context *context)
2024*8975f5c5SAndroid Build Coastguard Worker {
2025*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
2026*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
2027*8975f5c5SAndroid Build Coastguard Worker
2028*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
2029*8975f5c5SAndroid Build Coastguard Worker stateManager->deleteTexture(mTextureID);
2030*8975f5c5SAndroid Build Coastguard Worker
2031*8975f5c5SAndroid Build Coastguard Worker functions->genTextures(1, &mTextureID);
2032*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
2033*8975f5c5SAndroid Build Coastguard Worker
2034*8975f5c5SAndroid Build Coastguard Worker mLevelInfo.clear();
2035*8975f5c5SAndroid Build Coastguard Worker mLevelInfo.resize(GetMaxLevelInfoCountForTextureType(getType()));
2036*8975f5c5SAndroid Build Coastguard Worker
2037*8975f5c5SAndroid Build Coastguard Worker mAppliedSwizzle = gl::SwizzleState();
2038*8975f5c5SAndroid Build Coastguard Worker mAppliedSampler = gl::SamplerState::CreateDefaultForTarget(getType());
2039*8975f5c5SAndroid Build Coastguard Worker
2040*8975f5c5SAndroid Build Coastguard Worker mAppliedBaseLevel = 0;
2041*8975f5c5SAndroid Build Coastguard Worker mAppliedBaseLevel = gl::kInitialMaxLevel;
2042*8975f5c5SAndroid Build Coastguard Worker
2043*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits = mAllModifiedDirtyBits;
2044*8975f5c5SAndroid Build Coastguard Worker
2045*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::SubjectChanged);
2046*8975f5c5SAndroid Build Coastguard Worker
2047*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2048*8975f5c5SAndroid Build Coastguard Worker }
2049*8975f5c5SAndroid Build Coastguard Worker
syncTextureStateSwizzle(const gl::Context * context,const FunctionsGL * functions,GLenum name,GLenum value,GLenum * currentlyAppliedValue)2050*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::syncTextureStateSwizzle(const gl::Context *context,
2051*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions,
2052*8975f5c5SAndroid Build Coastguard Worker GLenum name,
2053*8975f5c5SAndroid Build Coastguard Worker GLenum value,
2054*8975f5c5SAndroid Build Coastguard Worker GLenum *currentlyAppliedValue)
2055*8975f5c5SAndroid Build Coastguard Worker {
2056*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &levelInfo = getBaseLevelInfo();
2057*8975f5c5SAndroid Build Coastguard Worker GLenum resultSwizzle = value;
2058*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.lumaWorkaround.enabled)
2059*8975f5c5SAndroid Build Coastguard Worker {
2060*8975f5c5SAndroid Build Coastguard Worker switch (value)
2061*8975f5c5SAndroid Build Coastguard Worker {
2062*8975f5c5SAndroid Build Coastguard Worker case GL_RED:
2063*8975f5c5SAndroid Build Coastguard Worker case GL_GREEN:
2064*8975f5c5SAndroid Build Coastguard Worker case GL_BLUE:
2065*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.sourceFormat == GL_LUMINANCE ||
2066*8975f5c5SAndroid Build Coastguard Worker levelInfo.sourceFormat == GL_LUMINANCE_ALPHA)
2067*8975f5c5SAndroid Build Coastguard Worker {
2068*8975f5c5SAndroid Build Coastguard Worker // Texture is backed by a RED or RG texture, point all color channels at the
2069*8975f5c5SAndroid Build Coastguard Worker // red channel.
2070*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED ||
2071*8975f5c5SAndroid Build Coastguard Worker levelInfo.lumaWorkaround.workaroundFormat == GL_RG);
2072*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_RED;
2073*8975f5c5SAndroid Build Coastguard Worker }
2074*8975f5c5SAndroid Build Coastguard Worker else
2075*8975f5c5SAndroid Build Coastguard Worker {
2076*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.sourceFormat == GL_ALPHA);
2077*8975f5c5SAndroid Build Coastguard Worker // Color channels are not supposed to exist, make them always sample 0.
2078*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_ZERO;
2079*8975f5c5SAndroid Build Coastguard Worker }
2080*8975f5c5SAndroid Build Coastguard Worker break;
2081*8975f5c5SAndroid Build Coastguard Worker
2082*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
2083*8975f5c5SAndroid Build Coastguard Worker if (levelInfo.sourceFormat == GL_LUMINANCE)
2084*8975f5c5SAndroid Build Coastguard Worker {
2085*8975f5c5SAndroid Build Coastguard Worker // Alpha channel is not supposed to exist, make it always sample 1.
2086*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_ONE;
2087*8975f5c5SAndroid Build Coastguard Worker }
2088*8975f5c5SAndroid Build Coastguard Worker else if (levelInfo.sourceFormat == GL_ALPHA)
2089*8975f5c5SAndroid Build Coastguard Worker {
2090*8975f5c5SAndroid Build Coastguard Worker // Texture is backed by a RED texture, point the alpha channel at the red
2091*8975f5c5SAndroid Build Coastguard Worker // channel.
2092*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RED);
2093*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_RED;
2094*8975f5c5SAndroid Build Coastguard Worker }
2095*8975f5c5SAndroid Build Coastguard Worker else
2096*8975f5c5SAndroid Build Coastguard Worker {
2097*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.sourceFormat == GL_LUMINANCE_ALPHA);
2098*8975f5c5SAndroid Build Coastguard Worker // Texture is backed by an RG texture, point the alpha channel at the green
2099*8975f5c5SAndroid Build Coastguard Worker // channel.
2100*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelInfo.lumaWorkaround.workaroundFormat == GL_RG);
2101*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_GREEN;
2102*8975f5c5SAndroid Build Coastguard Worker }
2103*8975f5c5SAndroid Build Coastguard Worker break;
2104*8975f5c5SAndroid Build Coastguard Worker
2105*8975f5c5SAndroid Build Coastguard Worker case GL_ZERO:
2106*8975f5c5SAndroid Build Coastguard Worker case GL_ONE:
2107*8975f5c5SAndroid Build Coastguard Worker // Don't modify the swizzle state when requesting ZERO or ONE.
2108*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = value;
2109*8975f5c5SAndroid Build Coastguard Worker break;
2110*8975f5c5SAndroid Build Coastguard Worker
2111*8975f5c5SAndroid Build Coastguard Worker default:
2112*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2113*8975f5c5SAndroid Build Coastguard Worker break;
2114*8975f5c5SAndroid Build Coastguard Worker }
2115*8975f5c5SAndroid Build Coastguard Worker }
2116*8975f5c5SAndroid Build Coastguard Worker else if (levelInfo.depthStencilWorkaround)
2117*8975f5c5SAndroid Build Coastguard Worker {
2118*8975f5c5SAndroid Build Coastguard Worker switch (value)
2119*8975f5c5SAndroid Build Coastguard Worker {
2120*8975f5c5SAndroid Build Coastguard Worker case GL_RED:
2121*8975f5c5SAndroid Build Coastguard Worker // Don't modify the swizzle state when requesting the red channel.
2122*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = value;
2123*8975f5c5SAndroid Build Coastguard Worker break;
2124*8975f5c5SAndroid Build Coastguard Worker
2125*8975f5c5SAndroid Build Coastguard Worker case GL_GREEN:
2126*8975f5c5SAndroid Build Coastguard Worker case GL_BLUE:
2127*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() <= 2)
2128*8975f5c5SAndroid Build Coastguard Worker {
2129*8975f5c5SAndroid Build Coastguard Worker // In OES_depth_texture/ARB_depth_texture, depth
2130*8975f5c5SAndroid Build Coastguard Worker // textures are treated as luminance.
2131*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_RED;
2132*8975f5c5SAndroid Build Coastguard Worker }
2133*8975f5c5SAndroid Build Coastguard Worker else
2134*8975f5c5SAndroid Build Coastguard Worker {
2135*8975f5c5SAndroid Build Coastguard Worker // In GLES 3.0, depth textures are treated as RED
2136*8975f5c5SAndroid Build Coastguard Worker // textures, so green and blue should be 0.
2137*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_ZERO;
2138*8975f5c5SAndroid Build Coastguard Worker }
2139*8975f5c5SAndroid Build Coastguard Worker break;
2140*8975f5c5SAndroid Build Coastguard Worker
2141*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
2142*8975f5c5SAndroid Build Coastguard Worker // Depth textures should sample 1 from the alpha channel.
2143*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_ONE;
2144*8975f5c5SAndroid Build Coastguard Worker break;
2145*8975f5c5SAndroid Build Coastguard Worker
2146*8975f5c5SAndroid Build Coastguard Worker case GL_ZERO:
2147*8975f5c5SAndroid Build Coastguard Worker case GL_ONE:
2148*8975f5c5SAndroid Build Coastguard Worker // Don't modify the swizzle state when requesting ZERO or ONE.
2149*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = value;
2150*8975f5c5SAndroid Build Coastguard Worker break;
2151*8975f5c5SAndroid Build Coastguard Worker
2152*8975f5c5SAndroid Build Coastguard Worker default:
2153*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
2154*8975f5c5SAndroid Build Coastguard Worker break;
2155*8975f5c5SAndroid Build Coastguard Worker }
2156*8975f5c5SAndroid Build Coastguard Worker }
2157*8975f5c5SAndroid Build Coastguard Worker else if (levelInfo.emulatedAlphaChannel)
2158*8975f5c5SAndroid Build Coastguard Worker {
2159*8975f5c5SAndroid Build Coastguard Worker if (value == GL_ALPHA)
2160*8975f5c5SAndroid Build Coastguard Worker {
2161*8975f5c5SAndroid Build Coastguard Worker resultSwizzle = GL_ONE;
2162*8975f5c5SAndroid Build Coastguard Worker }
2163*8975f5c5SAndroid Build Coastguard Worker }
2164*8975f5c5SAndroid Build Coastguard Worker
2165*8975f5c5SAndroid Build Coastguard Worker if (*currentlyAppliedValue != resultSwizzle)
2166*8975f5c5SAndroid Build Coastguard Worker {
2167*8975f5c5SAndroid Build Coastguard Worker *currentlyAppliedValue = resultSwizzle;
2168*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->texParameteri(ToGLenum(getType()), name, resultSwizzle));
2169*8975f5c5SAndroid Build Coastguard Worker }
2170*8975f5c5SAndroid Build Coastguard Worker
2171*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2172*8975f5c5SAndroid Build Coastguard Worker }
2173*8975f5c5SAndroid Build Coastguard Worker
setLevelInfo(const gl::Context * context,gl::TextureTarget target,size_t level,size_t levelCount,const LevelInfoGL & levelInfo)2174*8975f5c5SAndroid Build Coastguard Worker void TextureGL::setLevelInfo(const gl::Context *context,
2175*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target,
2176*8975f5c5SAndroid Build Coastguard Worker size_t level,
2177*8975f5c5SAndroid Build Coastguard Worker size_t levelCount,
2178*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &levelInfo)
2179*8975f5c5SAndroid Build Coastguard Worker {
2180*8975f5c5SAndroid Build Coastguard Worker ASSERT(levelCount > 0);
2181*8975f5c5SAndroid Build Coastguard Worker
2182*8975f5c5SAndroid Build Coastguard Worker bool updateWorkarounds = levelInfo.depthStencilWorkaround || levelInfo.lumaWorkaround.enabled ||
2183*8975f5c5SAndroid Build Coastguard Worker levelInfo.emulatedAlphaChannel;
2184*8975f5c5SAndroid Build Coastguard Worker
2185*8975f5c5SAndroid Build Coastguard Worker bool updateDepthStencilTextureMode = false;
2186*8975f5c5SAndroid Build Coastguard Worker const bool setToDepthStencil = levelInfo.sourceFormat == GL_DEPTH_STENCIL;
2187*8975f5c5SAndroid Build Coastguard Worker
2188*8975f5c5SAndroid Build Coastguard Worker bool updateBorderColor = false;
2189*8975f5c5SAndroid Build Coastguard Worker const bool targetFormatHasBorderColorWorkarounds =
2190*8975f5c5SAndroid Build Coastguard Worker FormatHasBorderColorWorkarounds(levelInfo.sourceFormat);
2191*8975f5c5SAndroid Build Coastguard Worker
2192*8975f5c5SAndroid Build Coastguard Worker for (size_t i = level; i < level + levelCount; i++)
2193*8975f5c5SAndroid Build Coastguard Worker {
2194*8975f5c5SAndroid Build Coastguard Worker size_t index = GetLevelInfoIndex(target, i);
2195*8975f5c5SAndroid Build Coastguard Worker ASSERT(index < mLevelInfo.size());
2196*8975f5c5SAndroid Build Coastguard Worker auto &curLevelInfo = mLevelInfo[index];
2197*8975f5c5SAndroid Build Coastguard Worker
2198*8975f5c5SAndroid Build Coastguard Worker updateWorkarounds |= curLevelInfo.depthStencilWorkaround;
2199*8975f5c5SAndroid Build Coastguard Worker updateWorkarounds |= curLevelInfo.lumaWorkaround.enabled;
2200*8975f5c5SAndroid Build Coastguard Worker updateWorkarounds |= curLevelInfo.emulatedAlphaChannel;
2201*8975f5c5SAndroid Build Coastguard Worker
2202*8975f5c5SAndroid Build Coastguard Worker // When redefining a level to or from DEPTH_STENCIL
2203*8975f5c5SAndroid Build Coastguard Worker // format, ensure that the texture mode is synced.
2204*8975f5c5SAndroid Build Coastguard Worker const bool setFromDepthStencil = curLevelInfo.sourceFormat == GL_DEPTH_STENCIL;
2205*8975f5c5SAndroid Build Coastguard Worker if (setFromDepthStencil != setToDepthStencil)
2206*8975f5c5SAndroid Build Coastguard Worker {
2207*8975f5c5SAndroid Build Coastguard Worker updateDepthStencilTextureMode = true;
2208*8975f5c5SAndroid Build Coastguard Worker }
2209*8975f5c5SAndroid Build Coastguard Worker
2210*8975f5c5SAndroid Build Coastguard Worker // When redefining a level to or from a format that has border color workarounds,
2211*8975f5c5SAndroid Build Coastguard Worker // ensure that the texture border color is synced.
2212*8975f5c5SAndroid Build Coastguard Worker if (FormatHasBorderColorWorkarounds(curLevelInfo.sourceFormat) ||
2213*8975f5c5SAndroid Build Coastguard Worker targetFormatHasBorderColorWorkarounds)
2214*8975f5c5SAndroid Build Coastguard Worker {
2215*8975f5c5SAndroid Build Coastguard Worker updateBorderColor = true;
2216*8975f5c5SAndroid Build Coastguard Worker }
2217*8975f5c5SAndroid Build Coastguard Worker
2218*8975f5c5SAndroid Build Coastguard Worker curLevelInfo = levelInfo;
2219*8975f5c5SAndroid Build Coastguard Worker }
2220*8975f5c5SAndroid Build Coastguard Worker
2221*8975f5c5SAndroid Build Coastguard Worker // Skip this step when unsupported
2222*8975f5c5SAndroid Build Coastguard Worker updateDepthStencilTextureMode =
2223*8975f5c5SAndroid Build Coastguard Worker updateDepthStencilTextureMode && (context->getClientVersion() >= gl::ES_3_1 ||
2224*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().stencilTexturingANGLE);
2225*8975f5c5SAndroid Build Coastguard Worker
2226*8975f5c5SAndroid Build Coastguard Worker // Skip this step when unsupported
2227*8975f5c5SAndroid Build Coastguard Worker updateBorderColor = updateBorderColor && (context->getClientVersion() >= gl::ES_3_2 ||
2228*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureBorderClampAny());
2229*8975f5c5SAndroid Build Coastguard Worker
2230*8975f5c5SAndroid Build Coastguard Worker if (updateWorkarounds || updateDepthStencilTextureMode || updateBorderColor)
2231*8975f5c5SAndroid Build Coastguard Worker {
2232*8975f5c5SAndroid Build Coastguard Worker if (updateWorkarounds)
2233*8975f5c5SAndroid Build Coastguard Worker {
2234*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
2235*8975f5c5SAndroid Build Coastguard Worker }
2236*8975f5c5SAndroid Build Coastguard Worker if (updateDepthStencilTextureMode)
2237*8975f5c5SAndroid Build Coastguard Worker {
2238*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
2239*8975f5c5SAndroid Build Coastguard Worker }
2240*8975f5c5SAndroid Build Coastguard Worker if (updateBorderColor)
2241*8975f5c5SAndroid Build Coastguard Worker {
2242*8975f5c5SAndroid Build Coastguard Worker mLocalDirtyBits.set(gl::Texture::DIRTY_BIT_BORDER_COLOR);
2243*8975f5c5SAndroid Build Coastguard Worker }
2244*8975f5c5SAndroid Build Coastguard Worker onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
2245*8975f5c5SAndroid Build Coastguard Worker }
2246*8975f5c5SAndroid Build Coastguard Worker }
2247*8975f5c5SAndroid Build Coastguard Worker
setLevelInfo(const gl::Context * context,gl::TextureType type,size_t level,size_t levelCount,const LevelInfoGL & levelInfo)2248*8975f5c5SAndroid Build Coastguard Worker void TextureGL::setLevelInfo(const gl::Context *context,
2249*8975f5c5SAndroid Build Coastguard Worker gl::TextureType type,
2250*8975f5c5SAndroid Build Coastguard Worker size_t level,
2251*8975f5c5SAndroid Build Coastguard Worker size_t levelCount,
2252*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &levelInfo)
2253*8975f5c5SAndroid Build Coastguard Worker {
2254*8975f5c5SAndroid Build Coastguard Worker if (type == gl::TextureType::CubeMap)
2255*8975f5c5SAndroid Build Coastguard Worker {
2256*8975f5c5SAndroid Build Coastguard Worker for (gl::TextureTarget target : gl::AllCubeFaceTextureTargets())
2257*8975f5c5SAndroid Build Coastguard Worker {
2258*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, target, level, levelCount, levelInfo);
2259*8975f5c5SAndroid Build Coastguard Worker }
2260*8975f5c5SAndroid Build Coastguard Worker }
2261*8975f5c5SAndroid Build Coastguard Worker else
2262*8975f5c5SAndroid Build Coastguard Worker {
2263*8975f5c5SAndroid Build Coastguard Worker setLevelInfo(context, NonCubeTextureTypeToTarget(type), level, levelCount, levelInfo);
2264*8975f5c5SAndroid Build Coastguard Worker }
2265*8975f5c5SAndroid Build Coastguard Worker }
2266*8975f5c5SAndroid Build Coastguard Worker
getLevelInfo(gl::TextureTarget target,size_t level) const2267*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &TextureGL::getLevelInfo(gl::TextureTarget target, size_t level) const
2268*8975f5c5SAndroid Build Coastguard Worker {
2269*8975f5c5SAndroid Build Coastguard Worker return mLevelInfo[GetLevelInfoIndex(target, level)];
2270*8975f5c5SAndroid Build Coastguard Worker }
2271*8975f5c5SAndroid Build Coastguard Worker
getBaseLevelInfo() const2272*8975f5c5SAndroid Build Coastguard Worker const LevelInfoGL &TextureGL::getBaseLevelInfo() const
2273*8975f5c5SAndroid Build Coastguard Worker {
2274*8975f5c5SAndroid Build Coastguard Worker GLint effectiveBaseLevel = mState.getEffectiveBaseLevel();
2275*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget target = getType() == gl::TextureType::CubeMap
2276*8975f5c5SAndroid Build Coastguard Worker ? gl::kCubeMapTextureTargetMin
2277*8975f5c5SAndroid Build Coastguard Worker : gl::NonCubeTextureTypeToTarget(getType());
2278*8975f5c5SAndroid Build Coastguard Worker return getLevelInfo(target, effectiveBaseLevel);
2279*8975f5c5SAndroid Build Coastguard Worker }
2280*8975f5c5SAndroid Build Coastguard Worker
getType() const2281*8975f5c5SAndroid Build Coastguard Worker gl::TextureType TextureGL::getType() const
2282*8975f5c5SAndroid Build Coastguard Worker {
2283*8975f5c5SAndroid Build Coastguard Worker return mState.getType();
2284*8975f5c5SAndroid Build Coastguard Worker }
2285*8975f5c5SAndroid Build Coastguard Worker
initializeContents(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex)2286*8975f5c5SAndroid Build Coastguard Worker angle::Result TextureGL::initializeContents(const gl::Context *context,
2287*8975f5c5SAndroid Build Coastguard Worker GLenum binding,
2288*8975f5c5SAndroid Build Coastguard Worker const gl::ImageIndex &imageIndex)
2289*8975f5c5SAndroid Build Coastguard Worker {
2290*8975f5c5SAndroid Build Coastguard Worker ContextGL *contextGL = GetImplAs<ContextGL>(context);
2291*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
2292*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
2293*8975f5c5SAndroid Build Coastguard Worker const angle::FeaturesGL &features = GetFeaturesGL(context);
2294*8975f5c5SAndroid Build Coastguard Worker
2295*8975f5c5SAndroid Build Coastguard Worker bool shouldUseClear = !nativegl::SupportsTexImage(getType());
2296*8975f5c5SAndroid Build Coastguard Worker GLenum nativeInternalFormat =
2297*8975f5c5SAndroid Build Coastguard Worker getLevelInfo(imageIndex.getTarget(), imageIndex.getLevelIndex()).nativeInternalFormat;
2298*8975f5c5SAndroid Build Coastguard Worker if ((features.allowClearForRobustResourceInit.enabled || shouldUseClear) &&
2299*8975f5c5SAndroid Build Coastguard Worker nativegl::SupportsNativeRendering(functions, mState.getType(), nativeInternalFormat))
2300*8975f5c5SAndroid Build Coastguard Worker {
2301*8975f5c5SAndroid Build Coastguard Worker BlitGL *blitter = GetBlitGL(context);
2302*8975f5c5SAndroid Build Coastguard Worker
2303*8975f5c5SAndroid Build Coastguard Worker int levelDepth = mState.getImageDesc(imageIndex).size.depth;
2304*8975f5c5SAndroid Build Coastguard Worker
2305*8975f5c5SAndroid Build Coastguard Worker bool clearSucceeded = false;
2306*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(blitter->clearRenderableTexture(context, this, nativeInternalFormat, levelDepth,
2307*8975f5c5SAndroid Build Coastguard Worker imageIndex, &clearSucceeded));
2308*8975f5c5SAndroid Build Coastguard Worker if (clearSucceeded)
2309*8975f5c5SAndroid Build Coastguard Worker {
2310*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
2311*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2312*8975f5c5SAndroid Build Coastguard Worker }
2313*8975f5c5SAndroid Build Coastguard Worker }
2314*8975f5c5SAndroid Build Coastguard Worker
2315*8975f5c5SAndroid Build Coastguard Worker // Either the texture is not renderable or was incomplete when clearing, fall back to a data
2316*8975f5c5SAndroid Build Coastguard Worker // upload
2317*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::SupportsTexImage(getType()));
2318*8975f5c5SAndroid Build Coastguard Worker const gl::ImageDesc &desc = mState.getImageDesc(imageIndex);
2319*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat &internalFormatInfo = *desc.format.info;
2320*8975f5c5SAndroid Build Coastguard Worker
2321*8975f5c5SAndroid Build Coastguard Worker gl::PixelUnpackState unpackState;
2322*8975f5c5SAndroid Build Coastguard Worker unpackState.alignment = 1;
2323*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, unpackState));
2324*8975f5c5SAndroid Build Coastguard Worker
2325*8975f5c5SAndroid Build Coastguard Worker GLuint prevUnpackBuffer = stateManager->getBufferID(gl::BufferBinding::PixelUnpack);
2326*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, 0);
2327*8975f5c5SAndroid Build Coastguard Worker
2328*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
2329*8975f5c5SAndroid Build Coastguard Worker if (internalFormatInfo.compressed)
2330*8975f5c5SAndroid Build Coastguard Worker {
2331*8975f5c5SAndroid Build Coastguard Worker nativegl::CompressedTexSubImageFormat nativeSubImageFormat =
2332*8975f5c5SAndroid Build Coastguard Worker nativegl::GetCompressedSubTexImageFormat(functions, features,
2333*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.internalFormat);
2334*8975f5c5SAndroid Build Coastguard Worker
2335*8975f5c5SAndroid Build Coastguard Worker GLuint imageSize = 0;
2336*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL,
2337*8975f5c5SAndroid Build Coastguard Worker internalFormatInfo.computeCompressedImageSize(desc.size, &imageSize));
2338*8975f5c5SAndroid Build Coastguard Worker
2339*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *zero;
2340*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_ALLOC(contextGL, context->getZeroFilledBuffer(imageSize, &zero));
2341*8975f5c5SAndroid Build Coastguard Worker
2342*8975f5c5SAndroid Build Coastguard Worker // WebGL spec requires that zero data is uploaded to compressed textures even if it might
2343*8975f5c5SAndroid Build Coastguard Worker // not result in zero color data.
2344*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
2345*8975f5c5SAndroid Build Coastguard Worker {
2346*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->compressedTexSubImage2D(
2347*8975f5c5SAndroid Build Coastguard Worker ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(),
2348*8975f5c5SAndroid Build Coastguard Worker 0, 0, desc.size.width, desc.size.height,
2349*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.format, imageSize, zero->data()));
2350*8975f5c5SAndroid Build Coastguard Worker }
2351*8975f5c5SAndroid Build Coastguard Worker else
2352*8975f5c5SAndroid Build Coastguard Worker {
2353*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
2354*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context, functions->compressedTexSubImage3D(
2355*8975f5c5SAndroid Build Coastguard Worker ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(),
2356*8975f5c5SAndroid Build Coastguard Worker 0, 0, 0, desc.size.width, desc.size.height, desc.size.depth,
2357*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.format, imageSize, zero->data()));
2358*8975f5c5SAndroid Build Coastguard Worker }
2359*8975f5c5SAndroid Build Coastguard Worker }
2360*8975f5c5SAndroid Build Coastguard Worker else
2361*8975f5c5SAndroid Build Coastguard Worker {
2362*8975f5c5SAndroid Build Coastguard Worker nativegl::TexSubImageFormat nativeSubImageFormat = nativegl::GetTexSubImageFormat(
2363*8975f5c5SAndroid Build Coastguard Worker functions, features, internalFormatInfo.format, internalFormatInfo.type);
2364*8975f5c5SAndroid Build Coastguard Worker
2365*8975f5c5SAndroid Build Coastguard Worker GLuint imageSize = 0;
2366*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_MATH(contextGL, internalFormatInfo.computePackUnpackEndByte(
2367*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.type, desc.size, unpackState,
2368*8975f5c5SAndroid Build Coastguard Worker nativegl::UseTexImage3D(getType()), &imageSize));
2369*8975f5c5SAndroid Build Coastguard Worker
2370*8975f5c5SAndroid Build Coastguard Worker angle::MemoryBuffer *zero;
2371*8975f5c5SAndroid Build Coastguard Worker ANGLE_CHECK_GL_ALLOC(contextGL, context->getZeroFilledBuffer(imageSize, &zero));
2372*8975f5c5SAndroid Build Coastguard Worker
2373*8975f5c5SAndroid Build Coastguard Worker if (nativegl::UseTexImage2D(getType()))
2374*8975f5c5SAndroid Build Coastguard Worker {
2375*8975f5c5SAndroid Build Coastguard Worker if (features.uploadTextureDataInChunks.enabled)
2376*8975f5c5SAndroid Build Coastguard Worker {
2377*8975f5c5SAndroid Build Coastguard Worker gl::Box area(0, 0, 0, desc.size.width, desc.size.height, 1);
2378*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(setSubImageRowByRowWorkaround(
2379*8975f5c5SAndroid Build Coastguard Worker context, imageIndex.getTarget(), imageIndex.getLevelIndex(), area,
2380*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.format, nativeSubImageFormat.type, unpackState, nullptr,
2381*8975f5c5SAndroid Build Coastguard Worker kUploadTextureDataInChunksUploadSize, zero->data()));
2382*8975f5c5SAndroid Build Coastguard Worker }
2383*8975f5c5SAndroid Build Coastguard Worker else
2384*8975f5c5SAndroid Build Coastguard Worker {
2385*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
2386*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage2D(
2387*8975f5c5SAndroid Build Coastguard Worker ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0,
2388*8975f5c5SAndroid Build Coastguard Worker desc.size.width, desc.size.height, nativeSubImageFormat.format,
2389*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.type, zero->data()));
2390*8975f5c5SAndroid Build Coastguard Worker }
2391*8975f5c5SAndroid Build Coastguard Worker }
2392*8975f5c5SAndroid Build Coastguard Worker else
2393*8975f5c5SAndroid Build Coastguard Worker {
2394*8975f5c5SAndroid Build Coastguard Worker ASSERT(nativegl::UseTexImage3D(getType()));
2395*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_TRY(context,
2396*8975f5c5SAndroid Build Coastguard Worker functions->texSubImage3D(
2397*8975f5c5SAndroid Build Coastguard Worker ToGLenum(imageIndex.getTarget()), imageIndex.getLevelIndex(), 0, 0, 0,
2398*8975f5c5SAndroid Build Coastguard Worker desc.size.width, desc.size.height, desc.size.depth,
2399*8975f5c5SAndroid Build Coastguard Worker nativeSubImageFormat.format, nativeSubImageFormat.type, zero->data()));
2400*8975f5c5SAndroid Build Coastguard Worker }
2401*8975f5c5SAndroid Build Coastguard Worker }
2402*8975f5c5SAndroid Build Coastguard Worker
2403*8975f5c5SAndroid Build Coastguard Worker // Reset the pixel unpack state. Because this call is made after synchronizing dirty bits in a
2404*8975f5c5SAndroid Build Coastguard Worker // glTexImage call, we need to make sure that the texture data to be uploaded later has the
2405*8975f5c5SAndroid Build Coastguard Worker // expected unpack state.
2406*8975f5c5SAndroid Build Coastguard Worker ANGLE_TRY(stateManager->setPixelUnpackState(context, context->getState().getUnpackState()));
2407*8975f5c5SAndroid Build Coastguard Worker stateManager->bindBuffer(gl::BufferBinding::PixelUnpack, prevUnpackBuffer);
2408*8975f5c5SAndroid Build Coastguard Worker
2409*8975f5c5SAndroid Build Coastguard Worker contextGL->markWorkSubmitted();
2410*8975f5c5SAndroid Build Coastguard Worker return angle::Result::Continue;
2411*8975f5c5SAndroid Build Coastguard Worker }
2412*8975f5c5SAndroid Build Coastguard Worker
getRequiredExternalTextureImageUnits(const gl::Context * context)2413*8975f5c5SAndroid Build Coastguard Worker GLint TextureGL::getRequiredExternalTextureImageUnits(const gl::Context *context)
2414*8975f5c5SAndroid Build Coastguard Worker {
2415*8975f5c5SAndroid Build Coastguard Worker const FunctionsGL *functions = GetFunctionsGL(context);
2416*8975f5c5SAndroid Build Coastguard Worker StateManagerGL *stateManager = GetStateManagerGL(context);
2417*8975f5c5SAndroid Build Coastguard Worker
2418*8975f5c5SAndroid Build Coastguard Worker ASSERT(getType() == gl::TextureType::External);
2419*8975f5c5SAndroid Build Coastguard Worker stateManager->bindTexture(getType(), mTextureID);
2420*8975f5c5SAndroid Build Coastguard Worker
2421*8975f5c5SAndroid Build Coastguard Worker GLint result = 0;
2422*8975f5c5SAndroid Build Coastguard Worker functions->getTexParameteriv(ToGLenum(gl::NonCubeTextureTypeToTarget(getType())),
2423*8975f5c5SAndroid Build Coastguard Worker GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES, &result);
2424*8975f5c5SAndroid Build Coastguard Worker return result;
2425*8975f5c5SAndroid Build Coastguard Worker }
2426*8975f5c5SAndroid Build Coastguard Worker
2427*8975f5c5SAndroid Build Coastguard Worker } // namespace rx
2428