content/canvas/src/WebGLTexture.h

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef WEBGLTEXTURE_H_
michael@0 7 #define WEBGLTEXTURE_H_
michael@0 8
michael@0 9 #include "WebGLObjectModel.h"
michael@0 10 #include "WebGLFramebufferAttachable.h"
michael@0 11
michael@0 12 #include "nsWrapperCache.h"
michael@0 13
michael@0 14 #include "mozilla/LinkedList.h"
michael@0 15 #include <algorithm>
michael@0 16
michael@0 17 namespace mozilla {
michael@0 18
michael@0 19 // Zero is not an integer power of two.
michael@0 20 inline bool is_pot_assuming_nonnegative(GLsizei x)
michael@0 21 {
michael@0 22 return x && (x & (x-1)) == 0;
michael@0 23 }
michael@0 24
michael@0 25 // NOTE: When this class is switched to new DOM bindings, update the (then-slow)
michael@0 26 // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
michael@0 27 class WebGLTexture MOZ_FINAL
michael@0 28 : public nsWrapperCache
michael@0 29 , public WebGLRefCountedObject<WebGLTexture>
michael@0 30 , public LinkedListElement<WebGLTexture>
michael@0 31 , public WebGLContextBoundObject
michael@0 32 , public WebGLFramebufferAttachable
michael@0 33 {
michael@0 34 public:
michael@0 35 WebGLTexture(WebGLContext *context);
michael@0 36
michael@0 37 ~WebGLTexture() {
michael@0 38 DeleteOnce();
michael@0 39 }
michael@0 40
michael@0 41 void Delete();
michael@0 42
michael@0 43 bool HasEverBeenBound() const { return mHasEverBeenBound; }
michael@0 44 void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
michael@0 45 GLuint GLName() const { return mGLName; }
michael@0 46 GLenum Target() const { return mTarget; }
michael@0 47
michael@0 48 WebGLContext *GetParentObject() const {
michael@0 49 return Context();
michael@0 50 }
michael@0 51
michael@0 52 virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
michael@0 53
michael@0 54 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
michael@0 55 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
michael@0 56
michael@0 57 protected:
michael@0 58
michael@0 59 friend class WebGLContext;
michael@0 60 friend class WebGLFramebuffer;
michael@0 61
michael@0 62 bool mHasEverBeenBound;
michael@0 63 GLuint mGLName;
michael@0 64
michael@0 65 // we store information about the various images that are part of
michael@0 66 // this texture (cubemap faces, mipmap levels)
michael@0 67
michael@0 68 public:
michael@0 69
michael@0 70 class ImageInfo
michael@0 71 : public WebGLRectangleObject
michael@0 72 {
michael@0 73 public:
michael@0 74 ImageInfo()
michael@0 75 : mWebGLFormat(LOCAL_GL_NONE)
michael@0 76 , mWebGLType(LOCAL_GL_NONE)
michael@0 77 , mImageDataStatus(WebGLImageDataStatus::NoImageData)
michael@0 78 {}
michael@0 79
michael@0 80 ImageInfo(GLsizei width,
michael@0 81 GLsizei height,
michael@0 82 GLenum webGLFormat,
michael@0 83 GLenum webGLType,
michael@0 84 WebGLImageDataStatus status)
michael@0 85 : WebGLRectangleObject(width, height)
michael@0 86 , mWebGLFormat(webGLFormat)
michael@0 87 , mWebGLType(webGLType)
michael@0 88 , mImageDataStatus(status)
michael@0 89 {
michael@0 90 // shouldn't use this constructor to construct a null ImageInfo
michael@0 91 MOZ_ASSERT(status != WebGLImageDataStatus::NoImageData);
michael@0 92 }
michael@0 93
michael@0 94 bool operator==(const ImageInfo& a) const {
michael@0 95 return mImageDataStatus == a.mImageDataStatus &&
michael@0 96 mWidth == a.mWidth &&
michael@0 97 mHeight == a.mHeight &&
michael@0 98 mWebGLFormat == a.mWebGLFormat &&
michael@0 99 mWebGLType == a.mWebGLType;
michael@0 100 }
michael@0 101 bool operator!=(const ImageInfo& a) const {
michael@0 102 return !(*this == a);
michael@0 103 }
michael@0 104 bool IsSquare() const {
michael@0 105 return mWidth == mHeight;
michael@0 106 }
michael@0 107 bool IsPositive() const {
michael@0 108 return mWidth > 0 && mHeight > 0;
michael@0 109 }
michael@0 110 bool IsPowerOfTwo() const {
michael@0 111 return is_pot_assuming_nonnegative(mWidth) &&
michael@0 112 is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
michael@0 113 }
michael@0 114 bool HasUninitializedImageData() const {
michael@0 115 return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
michael@0 116 }
michael@0 117 int64_t MemoryUsage() const;
michael@0 118 /*! This is the format passed from JS to WebGL.
michael@0 119 * It can be converted to a value to be passed to driver with
michael@0 120 * DriverFormatsFromFormatAndType().
michael@0 121 */
michael@0 122 GLenum WebGLFormat() const { return mWebGLFormat; }
michael@0 123 /*! This is the type passed from JS to WebGL.
michael@0 124 * It can be converted to a value to be passed to driver with
michael@0 125 * DriverTypeFromType().
michael@0 126 */
michael@0 127 GLenum WebGLType() const { return mWebGLType; }
michael@0 128
michael@0 129 protected:
michael@0 130 GLenum mWebGLFormat; //!< This is the WebGL/GLES format
michael@0 131 GLenum mWebGLType; //!< This is the WebGL/GLES type
michael@0 132 WebGLImageDataStatus mImageDataStatus;
michael@0 133
michael@0 134 friend class WebGLTexture;
michael@0 135 };
michael@0 136
michael@0 137 private:
michael@0 138 static size_t FaceForTarget(GLenum target) {
michael@0 139 // Call this out explicitly:
michael@0 140 MOZ_ASSERT(target != LOCAL_GL_TEXTURE_CUBE_MAP);
michael@0 141 MOZ_ASSERT(target == LOCAL_GL_TEXTURE_2D ||
michael@0 142 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
michael@0 143 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z));
michael@0 144 return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
michael@0 145 }
michael@0 146
michael@0 147 ImageInfo& ImageInfoAtFace(size_t face, GLint level) {
michael@0 148 MOZ_ASSERT(face < mFacesCount, "wrong face index, must be 0 for TEXTURE_2D and at most 5 for cube maps");
michael@0 149
michael@0 150 // no need to check level as a wrong value would be caught by ElementAt().
michael@0 151 return mImageInfos.ElementAt(level * mFacesCount + face);
michael@0 152 }
michael@0 153
michael@0 154 const ImageInfo& ImageInfoAtFace(size_t face, GLint level) const {
michael@0 155 return const_cast<const ImageInfo&>(
michael@0 156 const_cast<WebGLTexture*>(this)->ImageInfoAtFace(face, level)
michael@0 157 );
michael@0 158 }
michael@0 159
michael@0 160 public:
michael@0 161 ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) {
michael@0 162 MOZ_ASSERT(imageTarget);
michael@0 163
michael@0 164 size_t face = FaceForTarget(imageTarget);
michael@0 165 return ImageInfoAtFace(face, level);
michael@0 166 }
michael@0 167
michael@0 168 const ImageInfo& ImageInfoAt(GLenum imageTarget, GLint level) const {
michael@0 169 return const_cast<WebGLTexture*>(this)->ImageInfoAt(imageTarget, level);
michael@0 170 }
michael@0 171
michael@0 172 bool HasImageInfoAt(GLenum imageTarget, GLint level) const {
michael@0 173 MOZ_ASSERT(imageTarget);
michael@0 174
michael@0 175 size_t face = FaceForTarget(imageTarget);
michael@0 176 CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
michael@0 177 return checked_index.isValid() &&
michael@0 178 checked_index.value() < mImageInfos.Length() &&
michael@0 179 ImageInfoAt(imageTarget, level).mImageDataStatus != WebGLImageDataStatus::NoImageData;
michael@0 180 }
michael@0 181
michael@0 182 ImageInfo& ImageInfoBase() {
michael@0 183 return ImageInfoAtFace(0, 0);
michael@0 184 }
michael@0 185
michael@0 186 const ImageInfo& ImageInfoBase() const {
michael@0 187 return ImageInfoAtFace(0, 0);
michael@0 188 }
michael@0 189
michael@0 190 int64_t MemoryUsage() const;
michael@0 191
michael@0 192 void SetImageDataStatus(GLenum imageTarget, GLint level, WebGLImageDataStatus newStatus) {
michael@0 193 MOZ_ASSERT(HasImageInfoAt(imageTarget, level));
michael@0 194 ImageInfo& imageInfo = ImageInfoAt(imageTarget, level);
michael@0 195 // there is no way to go from having image data to not having any
michael@0 196 MOZ_ASSERT(newStatus != WebGLImageDataStatus::NoImageData ||
michael@0 197 imageInfo.mImageDataStatus == WebGLImageDataStatus::NoImageData);
michael@0 198 if (imageInfo.mImageDataStatus != newStatus) {
michael@0 199 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
michael@0 200 }
michael@0 201 imageInfo.mImageDataStatus = newStatus;
michael@0 202 }
michael@0 203
michael@0 204 void DoDeferredImageInitialization(GLenum imageTarget, GLint level);
michael@0 205
michael@0 206 protected:
michael@0 207
michael@0 208 GLenum mTarget;
michael@0 209 GLenum mMinFilter, mMagFilter, mWrapS, mWrapT;
michael@0 210
michael@0 211 size_t mFacesCount, mMaxLevelWithCustomImages;
michael@0 212 nsTArray<ImageInfo> mImageInfos;
michael@0 213
michael@0 214 bool mHaveGeneratedMipmap;
michael@0 215 WebGLTextureFakeBlackStatus mFakeBlackStatus;
michael@0 216
michael@0 217 void EnsureMaxLevelWithCustomImagesAtLeast(size_t aMaxLevelWithCustomImages) {
michael@0 218 mMaxLevelWithCustomImages = std::max(mMaxLevelWithCustomImages, aMaxLevelWithCustomImages);
michael@0 219 mImageInfos.EnsureLengthAtLeast((mMaxLevelWithCustomImages + 1) * mFacesCount);
michael@0 220 }
michael@0 221
michael@0 222 bool CheckFloatTextureFilterParams() const {
michael@0 223 // Without OES_texture_float_linear, only NEAREST and NEAREST_MIMPAMP_NEAREST are supported
michael@0 224 return (mMagFilter == LOCAL_GL_NEAREST) &&
michael@0 225 (mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
michael@0 226 }
michael@0 227
michael@0 228 bool AreBothWrapModesClampToEdge() const {
michael@0 229 return mWrapS == LOCAL_GL_CLAMP_TO_EDGE && mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
michael@0 230 }
michael@0 231
michael@0 232 bool DoesTexture2DMipmapHaveAllLevelsConsistentlyDefined(GLenum texImageTarget) const;
michael@0 233
michael@0 234 public:
michael@0 235
michael@0 236 void Bind(GLenum aTarget);
michael@0 237
michael@0 238 void SetImageInfo(GLenum aTarget, GLint aLevel,
michael@0 239 GLsizei aWidth, GLsizei aHeight,
michael@0 240 GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus);
michael@0 241
michael@0 242 void SetMinFilter(GLenum aMinFilter) {
michael@0 243 mMinFilter = aMinFilter;
michael@0 244 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
michael@0 245 }
michael@0 246 void SetMagFilter(GLenum aMagFilter) {
michael@0 247 mMagFilter = aMagFilter;
michael@0 248 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
michael@0 249 }
michael@0 250 void SetWrapS(GLenum aWrapS) {
michael@0 251 mWrapS = aWrapS;
michael@0 252 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
michael@0 253 }
michael@0 254 void SetWrapT(GLenum aWrapT) {
michael@0 255 mWrapT = aWrapT;
michael@0 256 SetFakeBlackStatus(WebGLTextureFakeBlackStatus::Unknown);
michael@0 257 }
michael@0 258 GLenum MinFilter() const { return mMinFilter; }
michael@0 259
michael@0 260 bool DoesMinFilterRequireMipmap() const {
michael@0 261 return !(mMinFilter == LOCAL_GL_NEAREST || mMinFilter == LOCAL_GL_LINEAR);
michael@0 262 }
michael@0 263
michael@0 264 void SetGeneratedMipmap();
michael@0 265
michael@0 266 void SetCustomMipmap();
michael@0 267
michael@0 268 bool IsFirstImagePowerOfTwo() const {
michael@0 269 return ImageInfoBase().IsPowerOfTwo();
michael@0 270 }
michael@0 271
michael@0 272 bool AreAllLevel0ImageInfosEqual() const;
michael@0 273
michael@0 274 bool IsMipmapTexture2DComplete() const;
michael@0 275
michael@0 276 bool IsCubeComplete() const;
michael@0 277
michael@0 278 bool IsMipmapCubeComplete() const;
michael@0 279
michael@0 280 void SetFakeBlackStatus(WebGLTextureFakeBlackStatus x) {
michael@0 281 mFakeBlackStatus = x;
michael@0 282 mContext->SetFakeBlackStatus(WebGLContextFakeBlackStatus::Unknown);
michael@0 283 }
michael@0 284 // Returns the current fake-black-status, except if it was Unknown,
michael@0 285 // in which case this function resolves it first, so it never returns Unknown.
michael@0 286 WebGLTextureFakeBlackStatus ResolvedFakeBlackStatus();
michael@0 287 };
michael@0 288
michael@0 289 } // namespace mozilla
michael@0 290
michael@0 291 #endif

mercurial