Bumping manifests a=b2g-bump
[gecko.git] / dom / canvas / WebGLTexture.h
bloba2be3d5b8ab933befdd07beb1e93101eff066072
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 WEBGLTEXTURE_H_
7 #define WEBGLTEXTURE_H_
9 #include "WebGLBindableName.h"
10 #include "WebGLFramebufferAttachable.h"
11 #include "WebGLObjectModel.h"
13 #include "nsWrapperCache.h"
15 #include "mozilla/CheckedInt.h"
16 #include "mozilla/LinkedList.h"
17 #include <algorithm>
19 namespace mozilla {
21 // Zero is not an integer power of two.
22 inline bool is_pot_assuming_nonnegative(GLsizei x)
24 return x && (x & (x-1)) == 0;
27 // NOTE: When this class is switched to new DOM bindings, update the (then-slow)
28 // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
29 class WebGLTexture MOZ_FINAL
30 : public nsWrapperCache
31 , public WebGLBindableName
32 , public WebGLRefCountedObject<WebGLTexture>
33 , public LinkedListElement<WebGLTexture>
34 , public WebGLContextBoundObject
35 , public WebGLFramebufferAttachable
37 public:
38 WebGLTexture(WebGLContext *context);
40 void Delete();
42 WebGLContext *GetParentObject() const {
43 return Context();
46 virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
48 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
49 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
51 protected:
52 ~WebGLTexture() {
53 DeleteOnce();
56 friend class WebGLContext;
57 friend class WebGLFramebuffer;
59 // we store information about the various images that are part of
60 // this texture (cubemap faces, mipmap levels)
62 public:
64 class ImageInfo
65 : public WebGLRectangleObject
67 public:
68 ImageInfo()
69 : mWebGLFormat(LOCAL_GL_NONE)
70 , mWebGLType(LOCAL_GL_NONE)
71 , mImageDataStatus(WebGLImageDataStatus::NoImageData)
74 ImageInfo(GLsizei width,
75 GLsizei height,
76 GLenum webGLFormat,
77 GLenum webGLType,
78 WebGLImageDataStatus status)
79 : WebGLRectangleObject(width, height)
80 , mWebGLFormat(webGLFormat)
81 , mWebGLType(webGLType)
82 , mImageDataStatus(status)
84 // shouldn't use this constructor to construct a null ImageInfo
85 MOZ_ASSERT(status != WebGLImageDataStatus::NoImageData);
88 bool operator==(const ImageInfo& a) const {
89 return mImageDataStatus == a.mImageDataStatus &&
90 mWidth == a.mWidth &&
91 mHeight == a.mHeight &&
92 mWebGLFormat == a.mWebGLFormat &&
93 mWebGLType == a.mWebGLType;
95 bool operator!=(const ImageInfo& a) const {
96 return !(*this == a);
98 bool IsSquare() const {
99 return mWidth == mHeight;
101 bool IsPositive() const {
102 return mWidth > 0 && mHeight > 0;
104 bool IsPowerOfTwo() const {
105 return is_pot_assuming_nonnegative(mWidth) &&
106 is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
108 bool HasUninitializedImageData() const {
109 return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
111 int64_t MemoryUsage() const;
112 /*! This is the format passed from JS to WebGL.
113 * It can be converted to a value to be passed to driver with
114 * DriverFormatsFromFormatAndType().
116 GLenum WebGLFormat() const { return mWebGLFormat; }
117 /*! This is the type passed from JS to WebGL.
118 * It can be converted to a value to be passed to driver with
119 * DriverTypeFromType().
121 GLenum WebGLType() const { return mWebGLType; }
123 protected:
124 GLenum mWebGLFormat; //!< This is the WebGL/GLES format
125 GLenum mWebGLType; //!< This is the WebGL/GLES type
126 WebGLImageDataStatus mImageDataStatus;
128 friend class WebGLTexture;
131 private:
132 static size_t FaceForTarget(GLenum target) {
133 // Call this out explicitly:
134 MOZ_ASSERT(target != LOCAL_GL_TEXTURE_CUBE_MAP);
135 MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
136 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
137 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z));
138 return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
141 ImageInfo& ImageInfoAtFace(size_t face, GLint level) {
142 MOZ_ASSERT(face < mFacesCount, "wrong face index, must be 0 for TEXTURE_2D and at most 5 for cube maps");
144 // no need to check level as a wrong value would be caught by ElementAt().
145 return mImageInfos.ElementAt(level * mFacesCount + face);
148 const ImageInfo& ImageInfoAtFace(size_t face, GLint level) const {
149 return const_cast<const ImageInfo&>(
150 const_cast<WebGLTexture*>(this)->ImageInfoAtFace(face, level)
154 public:
155 ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) {
156 MOZ_ASSERT(imageTarget);
158 size_t face = FaceForTarget(imageTarget);
159 return ImageInfoAtFace(face, level);
162 const ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) const {
163 return const_cast<WebGLTexture*>(this)->ImageInfoAt(imageTarget, level);
166 bool HasImageInfoAt(GLenum imageTarget, GLint level) const {
167 MOZ_ASSERT(imageTarget);
169 size_t face = FaceForTarget(imageTarget);
170 CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
171 return checked_index.isValid() &&
172 checked_index.value() < mImageInfos.Length() &&
173 ImageInfoAt(imageTarget, level).mImageDataStatus != WebGLImageDataStatus::NoImageData;
176 ImageInfo& ImageInfoBase() {
177 return ImageInfoAtFace(0, 0);
180 const ImageInfo& ImageInfoBase() const {
181 return ImageInfoAtFace(0, 0);
184 int64_t MemoryUsage() const;
186 void SetImageDataStatus(GLenum imageTarget, GLint level, WebGLImageDataStatus newStatus) {
187 MOZ_ASSERT(HasImageInfoAt(imageTarget, level));
188 ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
189 // there is no way to go from having image data to not having any
190 MOZ_ASSERT(newStatus != WebGLImageDataStatus::NoImageData ||
191 imageInfo.mImageDataStatus == WebGLImageDataStatus::NoImageData);
192 if (imageInfo.mImageDataStatus != newStatus) {
193 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
195 imageInfo.mImageDataStatus = newStatus;
198 void DoDeferredImageInitialization(GLenum imageTarget, GLint level);
200 protected:
202 GLenum mMinFilter, mMagFilter, mWrapS, mWrapT;
204 size_t mFacesCount, mMaxLevelWithCustomImages;
205 nsTArray<ImageInfo> mImageInfos;
207 bool mHaveGeneratedMipmap;
208 WebGLTextureFakeBlackStatus mFakeBlackStatus;
210 void EnsureMaxLevelWithCustomImagesAtLeast(size_t aMaxLevelWithCustomImages) {
211 mMaxLevelWithCustomImages = std::max(mMaxLevelWithCustomImages, aMaxLevelWithCustomImages);
212 mImageInfos.EnsureLengthAtLeast((mMaxLevelWithCustomImages + 1) * mFacesCount);
215 bool CheckFloatTextureFilterParams() const {
216 // Without OES_texture_float_linear, only NEAREST and NEAREST_MIMPAMP_NEAREST are supported
217 return (mMagFilter == LOCAL_GL_NEAREST) &&
218 (mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
221 bool AreBothWrapModesClampToEdge() const {
222 return mWrapS == LOCAL_GL_CLAMP_TO_EDGE && mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
225 bool DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(GLenum texImageTarget) const;
227 public:
229 void Bind(GLenum aTarget);
231 void SetImageInfo(GLenum aTarget, GLint aLevel,
232 GLsizei aWidth, GLsizei aHeight,
233 GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus);
235 void SetMinFilter(GLenum aMinFilter) {
236 mMinFilter = aMinFilter;
237 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
239 void SetMagFilter(GLenum aMagFilter) {
240 mMagFilter = aMagFilter;
241 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
243 void SetWrapS(GLenum aWrapS) {
244 mWrapS = aWrapS;
245 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
247 void SetWrapT(GLenum aWrapT) {
248 mWrapT = aWrapT;
249 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
251 GLenum MinFilter() const { return mMinFilter; }
253 bool DoesMinFilterRequireMipmap() const {
254 return !(mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_LINEAR);
257 void SetGeneratedMipmap();
259 void SetCustomMipmap();
261 bool IsFirstImagePowerOfTwo() const {
262 return ImageInfoBase().IsPowerOfTwo();
265 bool AreAllLevel0ImageInfosEqual() const;
267 bool IsMipmapTexture2DComplete() const;
269 bool IsCubeComplete() const;
271 bool IsMipmapCubeComplete() const;
273 void SetFakeBlackStatus(WebGLTextureFakeBlackStatus x);
275 // Returns the current fake-black-status, except if it was Unknown,
276 // in which case this function resolves it first, so it never returns Unknown.
277 WebGLTextureFakeBlackStatus ResolvedFakeBlackStatus();
280 } // namespace mozilla
282 #endif