content/canvas/src/WebGLTexture.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial