GLTextureImage.h (9953B)
1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 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 GLTEXTUREIMAGE_H_ 7 #define GLTEXTUREIMAGE_H_ 8 9 #include "nsRegion.h" 10 #include "nsTArray.h" 11 #include "gfxTypes.h" 12 #include "GLContextTypes.h" 13 #include "mozilla/gfx/Rect.h" 14 #include "mozilla/RefPtr.h" 15 16 class gfxASurface; 17 18 namespace mozilla { 19 namespace gfx { 20 class DataSourceSurface; 21 class DrawTarget; 22 } // namespace gfx 23 } // namespace mozilla 24 25 namespace mozilla { 26 namespace gl { 27 class GLContext; 28 29 /** 30 * A TextureImage provides a mechanism to synchronize data from a 31 * surface to a texture in the server. TextureImages are associated 32 * with one and only one GLContext. 33 */ 34 class TextureImage { 35 NS_INLINE_DECL_REFCOUNTING(TextureImage) 36 public: 37 enum TextureState { 38 Created, // Texture created, but has not had glTexImage called to 39 // initialize it. 40 Allocated, // Texture memory exists, but contents are invalid. 41 Valid // Texture fully ready to use. 42 }; 43 44 enum Flags { 45 NoFlags = 0x0, 46 UseNearestFilter = 0x1, 47 OriginBottomLeft = 0x2, 48 DisallowBigImage = 0x4 49 }; 50 51 typedef gfxContentType ContentType; 52 typedef gfxImageFormat ImageFormat; 53 54 static already_AddRefed<TextureImage> Create( 55 GLContext* gl, const gfx::IntSize& aSize, 56 TextureImage::ContentType aContentType, GLenum aWrapMode, 57 TextureImage::Flags aFlags = TextureImage::NoFlags); 58 59 /** 60 * The Image may contain several textures for different regions (tiles). 61 * These functions iterate over each sub texture image tile. 62 */ 63 virtual void BeginBigImageIteration() {} 64 65 virtual bool NextTile() { return false; } 66 67 // Function prototype for a tile iteration callback. Returning false will 68 // cause iteration to be interrupted (i.e. the corresponding NextTile call 69 // will return false). 70 typedef bool (*BigImageIterationCallback)(TextureImage* aImage, 71 int aTileNumber, 72 void* aCallbackData); 73 74 // Sets a callback to be called every time NextTile is called. 75 virtual void SetIterationCallback(BigImageIterationCallback aCallback, 76 void* aCallbackData) {} 77 78 virtual gfx::IntRect GetTileRect(); 79 80 virtual GLuint GetTextureID() = 0; 81 82 virtual uint32_t GetTileCount() { return 1; } 83 84 /** 85 * Set this TextureImage's size, and ensure a texture has been 86 * allocated. 87 * After a resize, the contents are undefined. 88 */ 89 virtual void Resize(const gfx::IntSize& aSize) = 0; 90 91 /** 92 * Mark this texture as having valid contents. Call this after modifying 93 * the texture contents externally. 94 */ 95 virtual void MarkValid() {} 96 97 /** 98 * aSurf - the source surface to update from 99 * aRegion - the region in this image to update 100 * aSrcOffset - offset in the source to update from 101 * aDstOffset - offset in the destination to update to 102 */ 103 virtual bool DirectUpdate( 104 gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, 105 const gfx::IntPoint& aSrcOffset = gfx::IntPoint(0, 0), 106 const gfx::IntPoint& aDstOffset = gfx::IntPoint(0, 0)) = 0; 107 bool UpdateFromDataSource(gfx::DataSourceSurface* aSurf, 108 const nsIntRegion* aDstRegion = nullptr, 109 const gfx::IntPoint* aSrcOffset = nullptr, 110 const gfx::IntPoint* aDstOffset = nullptr); 111 112 virtual void BindTexture(GLenum aTextureUnit) = 0; 113 114 /** 115 * Returns the image format of the texture. Only valid after 116 * DirectUpdate has been called. 117 */ 118 virtual gfx::SurfaceFormat GetTextureFormat() { return mTextureFormat; } 119 120 /** Can be called safely at any time. */ 121 122 /** 123 * If this TextureImage has a permanent gfxASurface backing, 124 * return it. Otherwise return nullptr. 125 */ 126 virtual already_AddRefed<gfxASurface> GetBackingSurface() { return nullptr; } 127 128 gfx::IntSize GetSize() const; 129 ContentType GetContentType() const { return mContentType; } 130 GLenum GetWrapMode() const { return mWrapMode; } 131 132 void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter) { 133 mSamplingFilter = aSamplingFilter; 134 } 135 136 protected: 137 friend class GLContext; 138 139 void UpdateUploadSize(size_t amount); 140 141 /** 142 * After the ctor, the TextureImage is invalid. Implementations 143 * must allocate resources successfully before returning the new 144 * TextureImage from GLContext::CreateTextureImage(). That is, 145 * clients must not be given partially-constructed TextureImages. 146 */ 147 TextureImage(const gfx::IntSize& aSize, GLenum aWrapMode, 148 ContentType aContentType, Flags aFlags = NoFlags); 149 150 // Protected destructor, to discourage deletion outside of Release(): 151 virtual ~TextureImage() { UpdateUploadSize(0); } 152 153 virtual gfx::IntRect GetSrcTileRect(); 154 155 gfx::IntSize mSize; 156 GLenum mWrapMode; 157 ContentType mContentType; 158 gfx::SurfaceFormat mTextureFormat; 159 gfx::SamplingFilter mSamplingFilter; 160 Flags mFlags; 161 size_t mUploadSize; 162 }; 163 164 /** 165 * BasicTextureImage is the baseline TextureImage implementation --- 166 * it updates its texture by allocating a scratch buffer for the 167 * client to draw into, then using glTexSubImage2D() to upload the new 168 * pixels. Platforms must provide the code to create a new surface 169 * into which the updated pixels will be drawn, and the code to 170 * convert the update surface's pixels into an image on which we can 171 * glTexSubImage2D(). 172 */ 173 class BasicTextureImage : public TextureImage { 174 public: 175 virtual ~BasicTextureImage(); 176 177 BasicTextureImage(GLuint aTexture, const gfx::IntSize& aSize, 178 GLenum aWrapMode, ContentType aContentType, 179 GLContext* aContext, 180 TextureImage::Flags aFlags = TextureImage::NoFlags); 181 182 void BindTexture(GLenum aTextureUnit) override; 183 184 bool DirectUpdate( 185 gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, 186 const gfx::IntPoint& aSrcOffset = gfx::IntPoint(0, 0), 187 const gfx::IntPoint& aDstOffset = gfx::IntPoint(0, 0)) override; 188 GLuint GetTextureID() override { return mTexture; } 189 190 void MarkValid() override { mTextureState = Valid; } 191 192 void Resize(const gfx::IntSize& aSize) override; 193 194 protected: 195 GLuint mTexture; 196 TextureState mTextureState; 197 RefPtr<GLContext> mGLContext; 198 }; 199 200 /** 201 * A container class that complements many sub TextureImages into a big 202 * TextureImage. Aims to behave just like the real thing. 203 */ 204 205 class TiledTextureImage final : public TextureImage { 206 public: 207 TiledTextureImage( 208 GLContext* aGL, gfx::IntSize aSize, TextureImage::ContentType, 209 TextureImage::Flags aFlags = TextureImage::NoFlags, 210 TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN); 211 virtual ~TiledTextureImage(); 212 void DumpDiv(); 213 void Resize(const gfx::IntSize& aSize) override; 214 uint32_t GetTileCount() override; 215 void BeginBigImageIteration() override; 216 bool NextTile() override; 217 void SetIterationCallback(BigImageIterationCallback aCallback, 218 void* aCallbackData) override; 219 gfx::IntRect GetTileRect() override; 220 GLuint GetTextureID() override { 221 return mImages[mCurrentImage]->GetTextureID(); 222 } 223 bool DirectUpdate( 224 gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, 225 const gfx::IntPoint& aSrcOffset = gfx::IntPoint(0, 0), 226 const gfx::IntPoint& aDstOffset = gfx::IntPoint(0, 0)) override; 227 void BindTexture(GLenum) override; 228 229 protected: 230 gfx::IntRect GetSrcTileRect() override; 231 232 unsigned int mCurrentImage; 233 BigImageIterationCallback mIterationCallback; 234 void* mIterationCallbackData; 235 nsTArray<RefPtr<TextureImage> > mImages; 236 unsigned int mTileSize; 237 unsigned int mRows, mColumns; 238 GLContext* mGL; 239 TextureState mTextureState; 240 TextureImage::ImageFormat mImageFormat; 241 }; 242 243 /** 244 * Creates a TextureImage of the basic implementation, can be useful in cases 245 * where we know we don't want to use platform-specific TextureImage. 246 * In doubt, use GLContext::CreateTextureImage instead. 247 */ 248 already_AddRefed<TextureImage> CreateBasicTextureImage( 249 GLContext* aGL, const gfx::IntSize& aSize, 250 TextureImage::ContentType aContentType, GLenum aWrapMode, 251 TextureImage::Flags aFlags); 252 253 /** 254 * Creates a TiledTextureImage backed by platform-specific or basic 255 * TextureImages. In doubt, use GLContext::CreateTextureImage instead. 256 */ 257 already_AddRefed<TextureImage> CreateTiledTextureImage( 258 GLContext* aGL, const gfx::IntSize& aSize, 259 TextureImage::ContentType aContentType, TextureImage::Flags aFlags, 260 TextureImage::ImageFormat aImageFormat); 261 262 /** 263 * Return a valid, allocated TextureImage of |aSize| with 264 * |aContentType|. If |aContentType| is COLOR, |aImageFormat| can be used 265 * to hint at the preferred RGB format, however it is not necessarily 266 * respected. The TextureImage's texture is configured to use 267 * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by 268 * default, GL_LINEAR filtering. Specify 269 * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify 270 * |aFlags=OriginBottomLeft| if the image is origin-bottom-left, instead of the 271 * default origin-top-left. Return 272 * nullptr if creating the TextureImage fails. 273 * 274 * The returned TextureImage may only be used with this GLContext. 275 * Attempting to use the returned TextureImage after this 276 * GLContext is destroyed will result in undefined (and likely 277 * crashy) behavior. 278 */ 279 already_AddRefed<TextureImage> CreateTextureImage( 280 GLContext* gl, const gfx::IntSize& aSize, 281 TextureImage::ContentType aContentType, GLenum aWrapMode, 282 TextureImage::Flags aFlags = TextureImage::NoFlags, 283 TextureImage::ImageFormat aImageFormat = gfx::SurfaceFormat::UNKNOWN); 284 285 } // namespace gl 286 } // namespace mozilla 287 288 #endif /* GLTEXTUREIMAGE_H_ */