Bug 1729395 - Handle message sender going away during message processing r=robwu
[gecko.git] / dom / canvas / WebGLTexture.h
blobfec5d58584382ee67e2cc332e12966fccd81980f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef WEBGL_TEXTURE_H_
7 #define WEBGL_TEXTURE_H_
9 #include <algorithm>
10 #include <map>
11 #include <set>
12 #include <vector>
14 #include "mozilla/Assertions.h"
15 #include "mozilla/Casting.h"
16 #include "mozilla/CheckedInt.h"
17 #include "mozilla/dom/TypedArray.h"
19 #include "CacheInvalidator.h"
20 #include "WebGLObjectModel.h"
21 #include "WebGLStrongTypes.h"
22 #include "WebGLTypes.h"
24 namespace mozilla {
25 class ErrorResult;
26 class WebGLContext;
27 class WebGLFramebuffer;
28 class WebGLSampler;
29 struct FloatOrInt;
30 struct TexImageSource;
32 namespace dom {
33 class Element;
34 class HTMLVideoElement;
35 class ImageData;
36 class ArrayBufferViewOrSharedArrayBufferView;
37 } // namespace dom
39 namespace layers {
40 class Image;
41 } // namespace layers
43 namespace webgl {
44 struct DriverUnpackInfo;
45 struct FormatUsageInfo;
46 struct PackingInfo;
47 class TexUnpackBlob;
48 } // namespace webgl
50 bool DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target,
51 uint8_t dims);
53 namespace webgl {
55 struct SamplingState final {
56 // Only store that which changes validation.
57 TexMinFilter minFilter = LOCAL_GL_NEAREST_MIPMAP_LINEAR;
58 TexMagFilter magFilter = LOCAL_GL_LINEAR;
59 TexWrap wrapS = LOCAL_GL_REPEAT;
60 TexWrap wrapT = LOCAL_GL_REPEAT;
61 // TexWrap wrapR = LOCAL_GL_REPEAT;
62 // GLfloat minLod = -1000;
63 // GLfloat maxLod = 1000;
64 TexCompareMode compareMode = LOCAL_GL_NONE;
65 // TexCompareFunc compareFunc = LOCAL_GL_LEQUAL;
68 struct ImageInfo final {
69 static const ImageInfo kUndefined;
71 const webgl::FormatUsageInfo* mFormat = nullptr;
72 uint32_t mWidth = 0;
73 uint32_t mHeight = 0;
74 uint32_t mDepth = 0;
75 mutable Maybe<std::vector<bool>> mUninitializedSlices;
76 uint8_t mSamples = 0;
78 // -
80 size_t MemoryUsage() const;
82 bool IsDefined() const {
83 if (!mFormat) {
84 MOZ_ASSERT(!mWidth && !mHeight && !mDepth);
85 return false;
88 return true;
91 Maybe<ImageInfo> NextMip(GLenum target) const;
94 } // namespace webgl
96 class WebGLTexture final : public WebGLContextBoundObject,
97 public CacheInvalidator {
98 // Friends
99 friend class WebGLContext;
100 friend class WebGLFramebuffer;
102 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(WebGLTexture, override)
104 ////////////////////////////////////
105 // Members
106 public:
107 const GLuint mGLName;
109 protected:
110 TexTarget mTarget;
112 static const uint8_t kMaxFaceCount = 6;
113 uint8_t mFaceCount; // 6 for cube maps, 1 otherwise.
115 bool mImmutable; // Set by texStorage*
116 uint8_t mImmutableLevelCount;
118 uint32_t mBaseMipmapLevel; // Set by texParameter (defaults to 0)
119 uint32_t mMaxMipmapLevel; // Set by texParameter (defaults to 1000)
120 // You almost certainly don't want to query mMaxMipmapLevel.
121 // You almost certainly want MaxEffectiveMipmapLevel().
123 webgl::SamplingState mSamplingState;
125 mutable const GLint* mCurSwizzle =
126 nullptr; // nullptr means 'default swizzle'.
128 // -
130 struct CompletenessInfo final {
131 uint8_t levels = 0;
132 bool powerOfTwo = false;
133 bool mipmapComplete = false;
134 const webgl::FormatUsageInfo* usage = nullptr;
135 const char* incompleteReason = nullptr;
138 mutable CacheWeakMap<const WebGLSampler*, webgl::SampleableInfo>
139 mSamplingCache;
141 public:
142 Maybe<const CompletenessInfo> CalcCompletenessInfo(
143 bool ensureInit, bool skipMips = false) const;
144 Maybe<const webgl::SampleableInfo> CalcSampleableInfo(
145 const WebGLSampler*) const;
147 const webgl::SampleableInfo* GetSampleableInfo(const WebGLSampler*) const;
149 // -
151 const auto& Immutable() const { return mImmutable; }
152 const auto& ImmutableLevelCount() const { return mImmutableLevelCount; }
154 // ES3.0 p150
155 uint32_t Es3_level_base() const {
156 const auto level_prime_base = mBaseMipmapLevel;
157 const auto level_immut = mImmutableLevelCount;
159 if (!mImmutable) return level_prime_base;
160 return std::min(level_prime_base, level_immut - 1u);
162 uint32_t Es3_level_max() const {
163 const auto level_base = Es3_level_base();
164 const auto level_prime_max = mMaxMipmapLevel;
165 const auto level_immut = mImmutableLevelCount;
167 if (!mImmutable) return level_prime_max;
168 return std::min(std::max(level_base, level_prime_max), level_immut - 1u);
171 // GLES 3.0.5 p158: `q`
172 uint32_t Es3_q() const; // "effective max mip level"
174 // -
176 const auto& FaceCount() const { return mFaceCount; }
178 // We can just max this out to 31, which is the number of unsigned bits in
179 // GLsizei.
180 static const uint8_t kMaxLevelCount = 31;
182 // We store information about the various images that are part of this
183 // texture. (cubemap faces, mipmap levels)
184 webgl::ImageInfo mImageInfoArr[kMaxLevelCount * kMaxFaceCount];
186 ////////////////////////////////////
188 WebGLTexture(WebGLContext* webgl, GLuint tex);
190 TexTarget Target() const { return mTarget; }
192 protected:
193 ~WebGLTexture() override;
195 public:
196 ////////////////////////////////////
197 // GL calls
198 bool BindTexture(TexTarget texTarget);
199 void GenerateMipmap();
200 Maybe<double> GetTexParameter(GLenum pname) const;
201 void TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& param);
203 ////////////////////////////////////
204 // WebGLTextureUpload.cpp
206 protected:
207 void TexOrSubImageBlob(bool isSubImage, TexImageTarget target, GLint level,
208 GLenum internalFormat, GLint xOffset, GLint yOffset,
209 GLint zOffset, const webgl::PackingInfo& pi,
210 const webgl::TexUnpackBlob* blob);
212 bool ValidateTexImageSpecification(TexImageTarget target, uint32_t level,
213 const uvec3& size,
214 webgl::ImageInfo** const out_imageInfo);
215 bool ValidateTexImageSelection(TexImageTarget target, uint32_t level,
216 const uvec3& offset, const uvec3& size,
217 webgl::ImageInfo** const out_imageInfo);
219 bool ValidateUnpack(const webgl::TexUnpackBlob* blob, bool isFunc3D,
220 const webgl::PackingInfo& srcPI) const;
222 public:
223 void TexStorage(TexTarget target, uint32_t levels, GLenum sizedFormat,
224 const uvec3& size);
226 // TexSubImage iff `!respecFormat`
227 void TexImage(uint32_t level, GLenum respecFormat, const uvec3& offset,
228 const webgl::PackingInfo& pi, const webgl::TexUnpackBlobDesc&);
230 // CompressedTexSubImage iff `sub`
231 void CompressedTexImage(bool sub, GLenum imageTarget, uint32_t level,
232 GLenum formatEnum, const uvec3& offset,
233 const uvec3& size, const Range<const uint8_t>& src,
234 const uint32_t pboImageSize,
235 const Maybe<uint64_t>& pboOffset);
237 // CopyTexSubImage iff `!respecFormat`
238 void CopyTexImage(GLenum imageTarget, uint32_t level, GLenum respecFormat,
239 const uvec3& dstOffset, const ivec2& srcOffset,
240 const uvec2& size2);
242 ////////////////////////////////////
244 protected:
245 void ClampLevelBaseAndMax();
246 void RefreshSwizzle() const;
248 static uint8_t FaceForTarget(TexImageTarget texImageTarget) {
249 GLenum rawTexImageTarget = texImageTarget.get();
250 switch (rawTexImageTarget) {
251 case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
252 case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
253 case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
254 case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
255 case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
256 case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
257 return AutoAssertCast(rawTexImageTarget -
258 LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X);
260 default:
261 return 0;
265 public:
266 auto& ImageInfoAtFace(uint8_t face, uint32_t level) {
267 MOZ_ASSERT(face < mFaceCount);
268 MOZ_ASSERT(level < kMaxLevelCount);
269 size_t pos = (level * mFaceCount) + face;
270 return mImageInfoArr[pos];
273 const auto& ImageInfoAtFace(uint8_t face, uint32_t level) const {
274 return const_cast<WebGLTexture*>(this)->ImageInfoAtFace(face, level);
277 auto& ImageInfoAt(TexImageTarget texImageTarget, GLint level) {
278 const auto& face = FaceForTarget(texImageTarget);
279 return ImageInfoAtFace(face, level);
282 const auto& ImageInfoAt(TexImageTarget texImageTarget, GLint level) const {
283 return const_cast<WebGLTexture*>(this)->ImageInfoAt(texImageTarget, level);
286 const auto& BaseImageInfo() const {
287 if (mBaseMipmapLevel >= kMaxLevelCount) return webgl::ImageInfo::kUndefined;
289 return ImageInfoAtFace(0, mBaseMipmapLevel);
292 size_t MemoryUsage() const;
294 bool EnsureImageDataInitialized(TexImageTarget target, uint32_t level);
295 void PopulateMipChain(uint32_t maxLevel);
296 bool IsMipAndCubeComplete(uint32_t maxLevel, bool ensureInit,
297 bool* out_initFailed) const;
298 void Truncate();
300 bool IsCubeMap() const { return (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP); }
303 inline TexImageTarget TexImageTargetForTargetAndFace(TexTarget target,
304 uint8_t face) {
305 switch (target.get()) {
306 case LOCAL_GL_TEXTURE_2D:
307 case LOCAL_GL_TEXTURE_3D:
308 MOZ_ASSERT(face == 0);
309 return target.get();
310 case LOCAL_GL_TEXTURE_CUBE_MAP:
311 MOZ_ASSERT(face < 6);
312 return LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
313 default:
314 MOZ_CRASH("GFX: TexImageTargetForTargetAndFace");
318 already_AddRefed<mozilla::layers::Image> ImageFromVideo(
319 dom::HTMLVideoElement* elem);
321 bool IsTarget3D(TexImageTarget target);
323 GLenum DoTexImage(gl::GLContext* gl, TexImageTarget target, GLint level,
324 const webgl::DriverUnpackInfo* dui, GLsizei width,
325 GLsizei height, GLsizei depth, const void* data);
326 GLenum DoTexSubImage(gl::GLContext* gl, TexImageTarget target, GLint level,
327 GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
328 GLsizei height, GLsizei depth,
329 const webgl::PackingInfo& pi, const void* data);
330 GLenum DoCompressedTexSubImage(gl::GLContext* gl, TexImageTarget target,
331 GLint level, GLint xOffset, GLint yOffset,
332 GLint zOffset, GLsizei width, GLsizei height,
333 GLsizei depth, GLenum sizedUnpackFormat,
334 GLsizei dataSize, const void* data);
336 } // namespace mozilla
338 #endif // WEBGL_TEXTURE_H_