LCOV - code coverage report
Current view: top level - dom/canvas - WebGLTexture.h (source / functions) Hit Total Coverage
Test: output.info Lines: 4 55 7.3 %
Date: 2017-07-14 16:53:18 Functions: 1 24 4.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #ifndef WEBGL_TEXTURE_H_
       7             : #define WEBGL_TEXTURE_H_
       8             : 
       9             : #include <algorithm>
      10             : #include <map>
      11             : #include <set>
      12             : #include <vector>
      13             : 
      14             : #include "mozilla/Assertions.h"
      15             : #include "mozilla/CheckedInt.h"
      16             : #include "mozilla/dom/TypedArray.h"
      17             : #include "mozilla/LinkedList.h"
      18             : #include "nsWrapperCache.h"
      19             : 
      20             : #include "WebGLFramebufferAttachable.h"
      21             : #include "WebGLObjectModel.h"
      22             : #include "WebGLStrongTypes.h"
      23             : #include "WebGLTypes.h"
      24             : 
      25             : namespace mozilla {
      26             : class ErrorResult;
      27             : class WebGLContext;
      28             : struct FloatOrInt;
      29             : struct TexImageSource;
      30             : 
      31             : namespace dom {
      32             : class Element;
      33             : class HTMLVideoElement;
      34             : class ImageData;
      35             : class ArrayBufferViewOrSharedArrayBufferView;
      36             : } // namespace dom
      37             : 
      38             : namespace layers {
      39             : class Image;
      40             : } // namespace layers
      41             : 
      42             : namespace webgl {
      43             : struct DriverUnpackInfo;
      44             : struct FormatUsageInfo;
      45             : struct PackingInfo;
      46             : class TexUnpackBlob;
      47             : } // namespace webgl
      48             : 
      49             : 
      50             : bool
      51             : DoesTargetMatchDimensions(WebGLContext* webgl, TexImageTarget target, uint8_t dims,
      52             :                           const char* funcName);
      53             : 
      54             : 
      55             : // NOTE: When this class is switched to new DOM bindings, update the (then-slow)
      56             : // WrapObject calls in GetParameter and GetFramebufferAttachmentParameter.
      57             : class WebGLTexture final
      58             :     : public nsWrapperCache
      59             :     , public WebGLRefCountedObject<WebGLTexture>
      60             :     , public LinkedListElement<WebGLTexture>
      61             : {
      62             :     // Friends
      63             :     friend class WebGLContext;
      64             :     friend class WebGLFramebuffer;
      65             : 
      66             :     ////////////////////////////////////
      67             :     // Members
      68             : public:
      69             :     const GLuint mGLName;
      70             : 
      71             : protected:
      72             :     TexTarget mTarget;
      73             : 
      74             :     static const uint8_t kMaxFaceCount = 6;
      75             :     uint8_t mFaceCount; // 6 for cube maps, 1 otherwise.
      76             : 
      77             :     TexMinFilter mMinFilter;
      78             :     TexMagFilter mMagFilter;
      79             :     TexWrap mWrapS, mWrapT;
      80             : 
      81             :     bool mImmutable; // Set by texStorage*
      82             :     uint8_t mImmutableLevelCount;
      83             : 
      84             :     uint32_t mBaseMipmapLevel; // Set by texParameter (defaults to 0)
      85             :     uint32_t mMaxMipmapLevel;  // Set by texParameter (defaults to 1000)
      86             :     // You almost certainly don't want to query mMaxMipmapLevel.
      87             :     // You almost certainly want MaxEffectiveMipmapLevel().
      88             : 
      89             :     GLenum mTexCompareMode;
      90             : 
      91             :     // Resolvable optimizations:
      92             :     bool mIsResolved;
      93             :     FakeBlackType mResolved_FakeBlack;
      94             :     const GLint* mResolved_Swizzle; // nullptr means 'default swizzle'.
      95             : 
      96             : public:
      97             :     class ImageInfo;
      98             : 
      99             :     // numLevels = log2(size) + 1
     100             :     // numLevels(16k) = log2(16k) + 1 = 14 + 1 = 15
     101             :     // numLevels(1M) = log2(1M) + 1 = 19.9 + 1 ~= 21
     102             :     // Or we can just max this out to 31, which is the number of unsigned bits in GLsizei.
     103             :     static const uint8_t kMaxLevelCount = 31;
     104             : 
     105             :     // And in turn, it needs these forwards:
     106             : protected:
     107             :     // We need to forward these.
     108             :     void SetImageInfo(const char* funcName, ImageInfo* target, const ImageInfo& newInfo);
     109             :     void SetImageInfosAtLevel(const char* funcName, uint32_t level,
     110             :                               const ImageInfo& newInfo);
     111             : 
     112             : public:
     113             :     // We store information about the various images that are part of this
     114             :     // texture. (cubemap faces, mipmap levels)
     115             :     class ImageInfo
     116             :     {
     117             :         friend void WebGLTexture::SetImageInfo(const char* funcName, ImageInfo* target,
     118             :                                                const ImageInfo& newInfo);
     119             :         friend void WebGLTexture::SetImageInfosAtLevel(const char* funcName,
     120             :                                                        uint32_t level,
     121             :                                                        const ImageInfo& newInfo);
     122             : 
     123             :     public:
     124             :         static const ImageInfo kUndefined;
     125             : 
     126             :         // This is the "effective internal format" of the texture, an official
     127             :         // OpenGL spec concept, see OpenGL ES 3.0.3 spec, section 3.8.3, page
     128             :         // 126 and below.
     129             :         const webgl::FormatUsageInfo* const mFormat;
     130             : 
     131             :         const uint32_t mWidth;
     132             :         const uint32_t mHeight;
     133             :         const uint32_t mDepth;
     134             : 
     135             :     protected:
     136             :         bool mIsDataInitialized;
     137             : 
     138             :         std::set<WebGLFBAttachPoint*> mAttachPoints;
     139             : 
     140             :     public:
     141           3 :         ImageInfo()
     142           3 :             : mFormat(LOCAL_GL_NONE)
     143             :             , mWidth(0)
     144             :             , mHeight(0)
     145             :             , mDepth(0)
     146           3 :             , mIsDataInitialized(false)
     147           3 :         { }
     148             : 
     149           0 :         ImageInfo(const webgl::FormatUsageInfo* format, uint32_t width, uint32_t height,
     150             :                   uint32_t depth, bool isDataInitialized)
     151           0 :             : mFormat(format)
     152             :             , mWidth(width)
     153             :             , mHeight(height)
     154             :             , mDepth(depth)
     155           0 :             , mIsDataInitialized(isDataInitialized)
     156             :         {
     157           0 :             MOZ_ASSERT(mFormat);
     158           0 :         }
     159             : 
     160             :         void Clear(const char* funcName);
     161             : 
     162           0 :         ~ImageInfo() {
     163           0 :             MOZ_ASSERT(!mAttachPoints.size());
     164           0 :         }
     165             : 
     166             :     protected:
     167             :         void Set(const char* funcName, const ImageInfo& a);
     168             : 
     169             :     public:
     170           0 :         uint32_t PossibleMipmapLevels() const {
     171             :             // GLES 3.0.4, 3.8 - Mipmapping: `floor(log2(largest_of_dims)) + 1`
     172           0 :             const uint32_t largest = std::max(std::max(mWidth, mHeight), mDepth);
     173           0 :             MOZ_ASSERT(largest != 0);
     174           0 :             return FloorLog2Size(largest) + 1;
     175             :         }
     176             : 
     177             :         bool IsPowerOfTwo() const;
     178             : 
     179             :         void AddAttachPoint(WebGLFBAttachPoint* attachPoint);
     180             :         void RemoveAttachPoint(WebGLFBAttachPoint* attachPoint);
     181             :         void OnRespecify(const char* funcName) const;
     182             : 
     183             :         size_t MemoryUsage() const;
     184             : 
     185           0 :         bool IsDefined() const {
     186           0 :             if (mFormat == LOCAL_GL_NONE) {
     187           0 :                 MOZ_ASSERT(!mWidth && !mHeight && !mDepth);
     188           0 :                 return false;
     189             :             }
     190             : 
     191           0 :             return true;
     192             :         }
     193             : 
     194           0 :         bool IsDataInitialized() const { return mIsDataInitialized; }
     195             : 
     196             :         void SetIsDataInitialized(bool isDataInitialized, WebGLTexture* tex);
     197             :     };
     198             : 
     199             :     ImageInfo mImageInfoArr[kMaxLevelCount * kMaxFaceCount];
     200             : 
     201             :     ////////////////////////////////////
     202             : public:
     203           0 :     NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTexture)
     204           0 :     NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTexture)
     205             : 
     206             :     WebGLTexture(WebGLContext* webgl, GLuint tex);
     207             : 
     208             :     void Delete();
     209             : 
     210           0 :     bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
     211           0 :     TexTarget Target() const { return mTarget; }
     212             : 
     213           0 :     WebGLContext* GetParentObject() const {
     214           0 :         return mContext;
     215             :     }
     216             : 
     217             :     virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
     218             : 
     219             : protected:
     220           0 :     ~WebGLTexture() {
     221           0 :         DeleteOnce();
     222           0 :     }
     223             : 
     224             : public:
     225             :     ////////////////////////////////////
     226             :     // GL calls
     227             :     bool BindTexture(TexTarget texTarget);
     228             :     void GenerateMipmap(TexTarget texTarget);
     229             :     JS::Value GetTexParameter(TexTarget texTarget, GLenum pname);
     230             :     bool IsTexture() const;
     231             :     void TexParameter(TexTarget texTarget, GLenum pname, const FloatOrInt& param);
     232             : 
     233             :     ////////////////////////////////////
     234             :     // WebGLTextureUpload.cpp
     235             : 
     236             : protected:
     237             :     void TexOrSubImageBlob(bool isSubImage, const char* funcName, TexImageTarget target,
     238             :                            GLint level, GLenum internalFormat, GLint xOffset,
     239             :                            GLint yOffset, GLint zOffset,
     240             :                            const webgl::PackingInfo& pi,
     241             :                            const webgl::TexUnpackBlob* blob);
     242             : 
     243             :     bool ValidateTexImageSpecification(const char* funcName, TexImageTarget target,
     244             :                                        GLint level, uint32_t width, uint32_t height,
     245             :                                        uint32_t depth,
     246             :                                        WebGLTexture::ImageInfo** const out_imageInfo);
     247             :     bool ValidateTexImageSelection(const char* funcName, TexImageTarget target,
     248             :                                    GLint level, GLint xOffset, GLint yOffset,
     249             :                                    GLint zOffset, uint32_t width, uint32_t height,
     250             :                                    uint32_t depth,
     251             :                                    WebGLTexture::ImageInfo** const out_imageInfo);
     252             :     bool ValidateCopyTexImageForFeedback(const char* funcName, uint32_t level, GLint layer = 0) const;
     253             : 
     254             :     bool ValidateUnpack(const char* funcName, const webgl::TexUnpackBlob* blob,
     255             :                         bool isFunc3D, const webgl::PackingInfo& srcPI) const;
     256             : public:
     257             :     void TexStorage(const char* funcName, TexTarget target, GLsizei levels,
     258             :                     GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth);
     259             :     void TexImage(const char* funcName, TexImageTarget target, GLint level,
     260             :                   GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
     261             :                   GLint border, const webgl::PackingInfo& pi, const TexImageSource& src);
     262             :     void TexSubImage(const char* funcName, TexImageTarget target, GLint level,
     263             :                      GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
     264             :                      GLsizei height, GLsizei depth, const webgl::PackingInfo& pi,
     265             :                      const TexImageSource& src);
     266             : protected:
     267             :     void TexImage(const char* funcName, TexImageTarget target, GLint level,
     268             :                   GLenum internalFormat, const webgl::PackingInfo& pi,
     269             :                   const webgl::TexUnpackBlob* blob);
     270             :     void TexSubImage(const char* funcName, TexImageTarget target, GLint level,
     271             :                      GLint xOffset, GLint yOffset, GLint zOffset,
     272             :                      const webgl::PackingInfo& pi, const webgl::TexUnpackBlob* blob);
     273             : public:
     274             :     void CompressedTexImage(const char* funcName, TexImageTarget target, GLint level,
     275             :                             GLenum internalFormat, GLsizei width, GLsizei height,
     276             :                             GLsizei depth, GLint border, const TexImageSource& src);
     277             :     void CompressedTexSubImage(const char* funcName, TexImageTarget target, GLint level,
     278             :                                GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
     279             :                                GLsizei height, GLsizei depth, GLenum sizedUnpackFormat,
     280             :                                const TexImageSource& src);
     281             : 
     282             :     void CopyTexImage2D(TexImageTarget target, GLint level, GLenum internalFormat,
     283             :                         GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
     284             :     void CopyTexSubImage(const char* funcName, TexImageTarget target, GLint level,
     285             :                          GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y,
     286             :                          GLsizei width, GLsizei height);
     287             : 
     288             :     ////////////////////////////////////
     289             : 
     290             : protected:
     291             :     void ClampLevelBaseAndMax();
     292             : 
     293             :     void PopulateMipChain(const char* funcName, uint32_t baseLevel, uint32_t maxLevel);
     294             : 
     295             :     bool MaxEffectiveMipmapLevel(uint32_t texUnit, uint32_t* const out) const;
     296             : 
     297           0 :     static uint8_t FaceForTarget(TexImageTarget texImageTarget) {
     298           0 :         GLenum rawTexImageTarget = texImageTarget.get();
     299           0 :         switch (rawTexImageTarget) {
     300             :         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
     301             :         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
     302             :         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
     303             :         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
     304             :         case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
     305             :         case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
     306           0 :             return rawTexImageTarget - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
     307             : 
     308             :         default:
     309           0 :             return 0;
     310             :         }
     311             :     }
     312             : 
     313           0 :     ImageInfo& ImageInfoAtFace(uint8_t face, uint32_t level) {
     314           0 :         MOZ_ASSERT(face < mFaceCount);
     315           0 :         MOZ_ASSERT(level < kMaxLevelCount);
     316           0 :         size_t pos = (level * mFaceCount) + face;
     317           0 :         return mImageInfoArr[pos];
     318             :     }
     319             : 
     320           0 :     const ImageInfo& ImageInfoAtFace(uint8_t face, uint32_t level) const {
     321           0 :         return const_cast<WebGLTexture*>(this)->ImageInfoAtFace(face, level);
     322             :     }
     323             : 
     324             : public:
     325           0 :     ImageInfo& ImageInfoAt(TexImageTarget texImageTarget, GLint level) {
     326           0 :         auto face = FaceForTarget(texImageTarget);
     327           0 :         return ImageInfoAtFace(face, level);
     328             :     }
     329             : 
     330             :     const ImageInfo& ImageInfoAt(TexImageTarget texImageTarget, GLint level) const {
     331             :         return const_cast<WebGLTexture*>(this)->ImageInfoAt(texImageTarget, level);
     332             :     }
     333             : 
     334             :     void SetImageInfoAt(const char* funcName, TexImageTarget texImageTarget, GLint level,
     335             :                         const ImageInfo& val)
     336             :     {
     337             :         ImageInfo* target = &ImageInfoAt(texImageTarget, level);
     338             :         SetImageInfo(funcName, target, val);
     339             :     }
     340             : 
     341           0 :     const ImageInfo& BaseImageInfo() const {
     342           0 :         if (mBaseMipmapLevel >= kMaxLevelCount)
     343           0 :             return ImageInfo::kUndefined;
     344             : 
     345           0 :         return ImageInfoAtFace(0, mBaseMipmapLevel);
     346             :     }
     347             : 
     348             :     size_t MemoryUsage() const;
     349             : 
     350             :     bool InitializeImageData(const char* funcName, TexImageTarget target, uint32_t level);
     351             : protected:
     352             :     bool EnsureImageDataInitialized(const char* funcName, TexImageTarget target,
     353             :                                     uint32_t level);
     354             :     bool EnsureLevelInitialized(const char* funcName, uint32_t level);
     355             : 
     356             :     bool CheckFloatTextureFilterParams() const {
     357             :         // Without OES_texture_float_linear, only NEAREST and
     358             :         // NEAREST_MIMPAMP_NEAREST are supported.
     359             :         return mMagFilter == LOCAL_GL_NEAREST &&
     360             :                (mMinFilter == LOCAL_GL_NEAREST ||
     361             :                 mMinFilter == LOCAL_GL_NEAREST_MIPMAP_NEAREST);
     362             :     }
     363             : 
     364             :     bool AreBothWrapModesClampToEdge() const {
     365             :         return mWrapS == LOCAL_GL_CLAMP_TO_EDGE &&
     366             :                mWrapT == LOCAL_GL_CLAMP_TO_EDGE;
     367             :     }
     368             : 
     369             : public:
     370           0 :     bool DoesMinFilterRequireMipmap() const {
     371           0 :         return !(mMinFilter == LOCAL_GL_NEAREST ||
     372           0 :                  mMinFilter == LOCAL_GL_LINEAR);
     373             :     }
     374             : 
     375             :     void SetGeneratedMipmap();
     376             : 
     377             :     void SetCustomMipmap();
     378             : 
     379             :     bool AreAllLevel0ImageInfosEqual() const;
     380             : 
     381             :     bool IsMipmapComplete(const char* funcName, uint32_t texUnit,
     382             :                           bool* const out_initFailed);
     383             : 
     384             :     bool IsCubeComplete() const;
     385             : 
     386             :     bool IsComplete(const char* funcName, uint32_t texUnit, const char** const out_reason,
     387             :                     bool* const out_initFailed);
     388             : 
     389             :     bool IsMipmapCubeComplete() const;
     390             : 
     391           0 :     bool IsCubeMap() const { return (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP); }
     392             : 
     393             :     // Resolve cache optimizations
     394             : protected:
     395             :     bool GetFakeBlackType(const char* funcName, uint32_t texUnit,
     396             :                           FakeBlackType* const out_fakeBlack);
     397             : public:
     398             :     bool IsFeedback(WebGLContext* webgl, const char* funcName, uint32_t texUnit,
     399             :                     const std::vector<const WebGLFBAttachPoint*>& fbAttachments) const;
     400             : 
     401             :     bool ResolveForDraw(const char* funcName, uint32_t texUnit,
     402             :                         FakeBlackType* const out_fakeBlack);
     403             : 
     404           0 :     void InvalidateResolveCache() { mIsResolved = false; }
     405             : };
     406             : 
     407             : inline TexImageTarget
     408             : TexImageTargetForTargetAndFace(TexTarget target, uint8_t face)
     409             : {
     410             :     switch (target.get()) {
     411             :     case LOCAL_GL_TEXTURE_2D:
     412             :     case LOCAL_GL_TEXTURE_3D:
     413             :         MOZ_ASSERT(face == 0);
     414             :         return target.get();
     415             :     case LOCAL_GL_TEXTURE_CUBE_MAP:
     416             :         MOZ_ASSERT(face < 6);
     417             :         return LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
     418             :     default:
     419             :         MOZ_CRASH("GFX: TexImageTargetForTargetAndFace");
     420             :     }
     421             : }
     422             : 
     423             : already_AddRefed<mozilla::layers::Image>
     424             : ImageFromVideo(dom::HTMLVideoElement* elem);
     425             : 
     426             : bool
     427             : IsTarget3D(TexImageTarget target);
     428             : 
     429             : GLenum
     430             : DoTexImage(gl::GLContext* gl, TexImageTarget target, GLint level,
     431             :            const webgl::DriverUnpackInfo* dui, GLsizei width, GLsizei height,
     432             :            GLsizei depth, const void* data);
     433             : GLenum
     434             : DoTexSubImage(gl::GLContext* gl, TexImageTarget target, GLint level, GLint xOffset,
     435             :               GLint yOffset, GLint zOffset, GLsizei width, GLsizei height,
     436             :               GLsizei depth, const webgl::PackingInfo& pi, const void* data);
     437             : GLenum
     438             : DoCompressedTexSubImage(gl::GLContext* gl, TexImageTarget target, GLint level,
     439             :                         GLint xOffset, GLint yOffset, GLint zOffset, GLsizei width,
     440             :                         GLsizei height, GLsizei depth, GLenum sizedUnpackFormat,
     441             :                         GLsizei dataSize, const void* data);
     442             : 
     443             : } // namespace mozilla
     444             : 
     445             : #endif // WEBGL_TEXTURE_H_

Generated by: LCOV version 1.13