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/. */
6 #ifndef GLTEXTUREIMAGE_H_
7 #define GLTEXTUREIMAGE_H_
12 #include "GLContextTypes.h"
13 #include "mozilla/gfx/Rect.h"
14 #include "mozilla/RefPtr.h"
20 class DataSourceSurface
;
23 } // namespace mozilla
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.
35 NS_INLINE_DECL_REFCOUNTING(TextureImage
)
38 Created
, // Texture created, but has not had glTexImage called to
40 Allocated
, // Texture memory exists, but contents are invalid.
41 Valid
// Texture fully ready to use.
46 UseNearestFilter
= 0x1,
47 OriginBottomLeft
= 0x2,
48 DisallowBigImage
= 0x4
51 typedef gfxContentType ContentType
;
52 typedef gfxImageFormat ImageFormat
;
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
);
60 * The Image may contain several textures for different regions (tiles).
61 * These functions iterate over each sub texture image tile.
63 virtual void BeginBigImageIteration() {}
65 virtual bool NextTile() { return false; }
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
,
74 // Sets a callback to be called every time NextTile is called.
75 virtual void SetIterationCallback(BigImageIterationCallback aCallback
,
76 void* aCallbackData
) {}
78 virtual gfx::IntRect
GetTileRect();
80 virtual GLuint
GetTextureID() = 0;
82 virtual uint32_t GetTileCount() { return 1; }
85 * Set this TextureImage's size, and ensure a texture has been
87 * After a resize, the contents are undefined.
89 virtual void Resize(const gfx::IntSize
& aSize
) = 0;
92 * Mark this texture as having valid contents. Call this after modifying
93 * the texture contents externally.
95 virtual void MarkValid() {}
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
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);
112 virtual void BindTexture(GLenum aTextureUnit
) = 0;
115 * Returns the image format of the texture. Only valid after
116 * DirectUpdate has been called.
118 virtual gfx::SurfaceFormat
GetTextureFormat() { return mTextureFormat
; }
120 /** Can be called safely at any time. */
123 * If this TextureImage has a permanent gfxASurface backing,
124 * return it. Otherwise return nullptr.
126 virtual already_AddRefed
<gfxASurface
> GetBackingSurface() { return nullptr; }
128 gfx::IntSize
GetSize() const;
129 ContentType
GetContentType() const { return mContentType
; }
130 GLenum
GetWrapMode() const { return mWrapMode
; }
132 void SetSamplingFilter(gfx::SamplingFilter aSamplingFilter
) {
133 mSamplingFilter
= aSamplingFilter
;
137 friend class GLContext
;
139 void UpdateUploadSize(size_t amount
);
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.
147 TextureImage(const gfx::IntSize
& aSize
, GLenum aWrapMode
,
148 ContentType aContentType
, Flags aFlags
= NoFlags
);
150 // Protected destructor, to discourage deletion outside of Release():
151 virtual ~TextureImage() { UpdateUploadSize(0); }
153 virtual gfx::IntRect
GetSrcTileRect();
157 ContentType mContentType
;
158 gfx::SurfaceFormat mTextureFormat
;
159 gfx::SamplingFilter mSamplingFilter
;
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
173 class BasicTextureImage
: public TextureImage
{
175 virtual ~BasicTextureImage();
177 BasicTextureImage(GLuint aTexture
, const gfx::IntSize
& aSize
,
178 GLenum aWrapMode
, ContentType aContentType
,
180 TextureImage::Flags aFlags
= TextureImage::NoFlags
);
182 void BindTexture(GLenum aTextureUnit
) override
;
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
; }
190 void MarkValid() override
{ mTextureState
= Valid
; }
192 void Resize(const gfx::IntSize
& aSize
) override
;
196 TextureState mTextureState
;
197 RefPtr
<GLContext
> mGLContext
;
201 * A container class that complements many sub TextureImages into a big
202 * TextureImage. Aims to behave just like the real thing.
205 class TiledTextureImage final
: public TextureImage
{
208 GLContext
* aGL
, gfx::IntSize aSize
, TextureImage::ContentType
,
209 TextureImage::Flags aFlags
= TextureImage::NoFlags
,
210 TextureImage::ImageFormat aImageFormat
= gfx::SurfaceFormat::UNKNOWN
);
211 virtual ~TiledTextureImage();
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();
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
;
230 gfx::IntRect
GetSrcTileRect() override
;
232 unsigned int mCurrentImage
;
233 BigImageIterationCallback mIterationCallback
;
234 void* mIterationCallbackData
;
235 nsTArray
<RefPtr
<TextureImage
> > mImages
;
236 unsigned int mTileSize
;
237 unsigned int mRows
, mColumns
;
239 TextureState mTextureState
;
240 TextureImage::ImageFormat mImageFormat
;
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.
248 already_AddRefed
<TextureImage
> CreateBasicTextureImage(
249 GLContext
* aGL
, const gfx::IntSize
& aSize
,
250 TextureImage::ContentType aContentType
, GLenum aWrapMode
,
251 TextureImage::Flags aFlags
);
254 * Creates a TiledTextureImage backed by platform-specific or basic
255 * TextureImages. In doubt, use GLContext::CreateTextureImage instead.
257 already_AddRefed
<TextureImage
> CreateTiledTextureImage(
258 GLContext
* aGL
, const gfx::IntSize
& aSize
,
259 TextureImage::ContentType aContentType
, TextureImage::Flags aFlags
,
260 TextureImage::ImageFormat aImageFormat
);
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.
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
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
);
286 } // namespace mozilla
288 #endif /* GLTEXTUREIMAGE_H_ */