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