Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / gfx / gl / GLTextureImage.h
blobdc67f1028d02890de8a386e09967e55106220ad0
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/. */
6 #ifndef GLTEXTUREIMAGE_H_
7 #define GLTEXTUREIMAGE_H_
9 #include "nsAutoPtr.h"
10 #include "nsRegion.h"
11 #include "nsTArray.h"
12 #include "gfxTypes.h"
13 #include "GLContextTypes.h"
14 #include "GraphicsFilter.h"
15 #include "mozilla/gfx/Rect.h"
16 #include "mozilla/RefPtr.h"
18 class gfxASurface;
20 namespace mozilla {
21 namespace gfx {
22 class DataSourceSurface;
23 class DrawTarget;
27 namespace mozilla {
28 namespace gl {
29 class GLContext;
31 /**
32 * A TextureImage encapsulates a surface that can be drawn to by a
33 * Thebes gfxContext and (hopefully efficiently!) synchronized to a
34 * texture in the server. TextureImages are associated with one and
35 * only one GLContext.
37 * Implementation note: TextureImages attempt to unify two categories
38 * of backends
40 * (1) proxy to server-side object that can be bound to a texture;
41 * e.g. Pixmap on X11.
43 * (2) efficient manager of texture memory; e.g. by having clients draw
44 * into a scratch buffer which is then uploaded with
45 * glTexSubImage2D().
47 class TextureImage
49 NS_INLINE_DECL_REFCOUNTING(TextureImage)
50 public:
51 enum TextureState
53 Created, // Texture created, but has not had glTexImage called to initialize it.
54 Allocated, // Texture memory exists, but contents are invalid.
55 Valid // Texture fully ready to use.
58 enum Flags {
59 NoFlags = 0x0,
60 UseNearestFilter = 0x1,
61 OriginBottomLeft = 0x2,
62 DisallowBigImage = 0x4
65 typedef gfxContentType ContentType;
66 typedef gfxImageFormat ImageFormat;
68 static already_AddRefed<TextureImage> Create(
69 GLContext* gl,
70 const gfx::IntSize& aSize,
71 TextureImage::ContentType aContentType,
72 GLenum aWrapMode,
73 TextureImage::Flags aFlags = TextureImage::NoFlags);
75 /**
76 * Returns a gfxASurface for updating |aRegion| of the client's
77 * image if successul, nullptr if not. |aRegion|'s bounds must fit
78 * within Size(); its coordinate space (if any) is ignored. If
79 * the update begins successfully, the returned gfxASurface is
80 * owned by this. Otherwise, nullptr is returned.
82 * |aRegion| is an inout param: the returned region is what the
83 * client must repaint. Category (1) regions above can
84 * efficiently handle repaints to "scattered" regions, while (2)
85 * can only efficiently handle repaints to rects.
87 * Painting the returned surface outside of |aRegion| results
88 * in undefined behavior.
90 * BeginUpdate() calls cannot be "nested", and each successful
91 * BeginUpdate() must be followed by exactly one EndUpdate() (see
92 * below). Failure to do so can leave this in a possibly
93 * inconsistent state. Unsuccessful BeginUpdate()s must not be
94 * followed by EndUpdate().
96 virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion) = 0;
97 /**
98 * Retrieves the region that will require updating, given a
99 * region that needs to be updated. This can be used for
100 * making decisions about updating before calling BeginUpdate().
102 * |aRegion| is an inout param.
104 virtual void GetUpdateRegion(nsIntRegion& aForRegion) {
107 * Finish the active update and synchronize with the server, if
108 * necessary.
110 * BeginUpdate() must have been called exactly once before
111 * EndUpdate().
113 virtual void EndUpdate() = 0;
116 * The Image may contain several textures for different regions (tiles).
117 * These functions iterate over each sub texture image tile.
119 virtual void BeginBigImageIteration() {
122 virtual bool NextTile() {
123 return false;
126 // Function prototype for a tile iteration callback. Returning false will
127 // cause iteration to be interrupted (i.e. the corresponding NextTile call
128 // will return false).
129 typedef bool (* BigImageIterationCallback)(TextureImage* aImage,
130 int aTileNumber,
131 void* aCallbackData);
133 // Sets a callback to be called every time NextTile is called.
134 virtual void SetIterationCallback(BigImageIterationCallback aCallback,
135 void* aCallbackData) {
138 virtual gfx::IntRect GetTileRect();
140 virtual GLuint GetTextureID() = 0;
142 virtual uint32_t GetTileCount() {
143 return 1;
147 * Set this TextureImage's size, and ensure a texture has been
148 * allocated. Must not be called between BeginUpdate and EndUpdate.
149 * After a resize, the contents are undefined.
151 * If this isn't implemented by a subclass, it will just perform
152 * a dummy BeginUpdate/EndUpdate pair.
154 virtual void Resize(const gfx::IntSize& aSize) {
155 mSize = aSize;
156 nsIntRegion r(nsIntRect(0, 0, aSize.width, aSize.height));
157 BeginUpdate(r);
158 EndUpdate();
162 * Mark this texture as having valid contents. Call this after modifying
163 * the texture contents externally.
165 virtual void MarkValid() {}
168 * aSurf - the source surface to update from
169 * aRegion - the region in this image to update
170 * aFrom - offset in the source to update from
172 virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) = 0;
173 bool UpdateFromDataSource(gfx::DataSourceSurface *aSurf,
174 const nsIntRegion* aDstRegion = nullptr,
175 const gfx::IntPoint* aSrcOffset = nullptr);
177 virtual void BindTexture(GLenum aTextureUnit) = 0;
180 * Returns the image format of the texture. Only valid after a matching
181 * BeginUpdate/EndUpdate pair have been called.
183 virtual gfx::SurfaceFormat GetTextureFormat() {
184 return mTextureFormat;
187 /** Can be called safely at any time. */
190 * If this TextureImage has a permanent gfxASurface backing,
191 * return it. Otherwise return nullptr.
193 virtual already_AddRefed<gfxASurface> GetBackingSurface()
194 { return nullptr; }
197 gfx::IntSize GetSize() const;
198 ContentType GetContentType() const { return mContentType; }
199 ImageFormat GetImageFormat() const { return mImageFormat; }
200 virtual bool InUpdate() const = 0;
201 GLenum GetWrapMode() const { return mWrapMode; }
203 void SetFilter(GraphicsFilter aFilter) { mFilter = aFilter; }
205 protected:
206 friend class GLContext;
209 * After the ctor, the TextureImage is invalid. Implementations
210 * must allocate resources successfully before returning the new
211 * TextureImage from GLContext::CreateTextureImage(). That is,
212 * clients must not be given partially-constructed TextureImages.
214 TextureImage(const nsIntSize& aSize,
215 GLenum aWrapMode, ContentType aContentType,
216 Flags aFlags = NoFlags,
217 ImageFormat aImageFormat = gfxImageFormat::Unknown)
218 : mSize(aSize.ToIntSize())
219 , mWrapMode(aWrapMode)
220 , mContentType(aContentType)
221 , mImageFormat(aImageFormat)
222 , mFilter(GraphicsFilter::FILTER_GOOD)
223 , mFlags(aFlags)
226 // Moz2D equivalent...
227 TextureImage(const gfx::IntSize& aSize,
228 GLenum aWrapMode, ContentType aContentType,
229 Flags aFlags = NoFlags);
231 // Protected destructor, to discourage deletion outside of Release():
232 virtual ~TextureImage() {}
234 virtual gfx::IntRect GetSrcTileRect();
236 gfx::IntSize mSize;
237 GLenum mWrapMode;
238 ContentType mContentType;
239 ImageFormat mImageFormat;
240 gfx::SurfaceFormat mTextureFormat;
241 GraphicsFilter mFilter;
242 Flags mFlags;
246 * BasicTextureImage is the baseline TextureImage implementation ---
247 * it updates its texture by allocating a scratch buffer for the
248 * client to draw into, then using glTexSubImage2D() to upload the new
249 * pixels. Platforms must provide the code to create a new surface
250 * into which the updated pixels will be drawn, and the code to
251 * convert the update surface's pixels into an image on which we can
252 * glTexSubImage2D().
254 class BasicTextureImage
255 : public TextureImage
257 public:
258 virtual ~BasicTextureImage();
260 BasicTextureImage(GLuint aTexture,
261 const nsIntSize& aSize,
262 GLenum aWrapMode,
263 ContentType aContentType,
264 GLContext* aContext,
265 TextureImage::Flags aFlags = TextureImage::NoFlags,
266 TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
267 BasicTextureImage(GLuint aTexture,
268 const gfx::IntSize& aSize,
269 GLenum aWrapMode,
270 ContentType aContentType,
271 GLContext* aContext,
272 TextureImage::Flags aFlags = TextureImage::NoFlags,
273 TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
275 virtual void BindTexture(GLenum aTextureUnit);
277 virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion);
278 virtual void GetUpdateRegion(nsIntRegion& aForRegion);
279 virtual void EndUpdate();
280 virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
281 virtual GLuint GetTextureID() { return mTexture; }
282 virtual TemporaryRef<gfx::DrawTarget>
283 GetDrawTargetForUpdate(const gfx::IntSize& aSize, gfx::SurfaceFormat aFmt);
285 virtual void MarkValid() { mTextureState = Valid; }
287 // Call when drawing into the update surface is complete.
288 // Returns true if textures should be upload with a relative
289 // offset - See UploadSurfaceToTexture.
290 virtual bool FinishedSurfaceUpdate();
292 // Call after surface data has been uploaded to a texture.
293 virtual void FinishedSurfaceUpload();
295 virtual bool InUpdate() const { return !!mUpdateDrawTarget; }
297 virtual void Resize(const gfx::IntSize& aSize);
299 protected:
300 GLuint mTexture;
301 TextureState mTextureState;
302 nsRefPtr<GLContext> mGLContext;
303 RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
304 nsIntRegion mUpdateRegion;
306 // The offset into the update surface at which the update rect is located.
307 nsIntPoint mUpdateOffset;
311 * A container class that complements many sub TextureImages into a big TextureImage.
312 * Aims to behave just like the real thing.
315 class TiledTextureImage MOZ_FINAL
316 : public TextureImage
318 public:
319 TiledTextureImage(GLContext* aGL,
320 gfx::IntSize aSize,
321 TextureImage::ContentType,
322 TextureImage::Flags aFlags = TextureImage::NoFlags,
323 TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
324 ~TiledTextureImage();
325 void DumpDiv();
326 virtual gfx::DrawTarget* BeginUpdate(nsIntRegion& aRegion);
327 virtual void GetUpdateRegion(nsIntRegion& aForRegion);
328 virtual void EndUpdate();
329 virtual void Resize(const gfx::IntSize& aSize);
330 virtual uint32_t GetTileCount();
331 virtual void BeginBigImageIteration();
332 virtual bool NextTile();
333 virtual void SetIterationCallback(BigImageIterationCallback aCallback,
334 void* aCallbackData);
335 virtual gfx::IntRect GetTileRect();
336 virtual GLuint GetTextureID() {
337 return mImages[mCurrentImage]->GetTextureID();
339 virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0));
340 virtual bool InUpdate() const { return mInUpdate; }
341 virtual void BindTexture(GLenum);
343 protected:
344 virtual gfx::IntRect GetSrcTileRect();
346 unsigned int mCurrentImage;
347 BigImageIterationCallback mIterationCallback;
348 void* mIterationCallbackData;
349 nsTArray< nsRefPtr<TextureImage> > mImages;
350 bool mInUpdate;
351 gfx::IntSize mSize;
352 unsigned int mTileSize;
353 unsigned int mRows, mColumns;
354 GLContext* mGL;
355 // A temporary draw target to faciliate cross-tile updates.
356 RefPtr<gfx::DrawTarget> mUpdateDrawTarget;
357 // The region of update requested
358 nsIntRegion mUpdateRegion;
359 TextureState mTextureState;
360 TextureImage::ImageFormat mImageFormat;
364 * Creates a TextureImage of the basic implementation, can be useful in cases
365 * where we know we don't want to use platform-specific TextureImage.
366 * In doubt, use GLContext::CreateTextureImage instead.
368 already_AddRefed<TextureImage>
369 CreateBasicTextureImage(GLContext* aGL,
370 const gfx::IntSize& aSize,
371 TextureImage::ContentType aContentType,
372 GLenum aWrapMode,
373 TextureImage::Flags aFlags,
374 TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
377 * Return a valid, allocated TextureImage of |aSize| with
378 * |aContentType|. If |aContentType| is COLOR, |aImageFormat| can be used
379 * to hint at the preferred RGB format, however it is not necessarily
380 * respected. The TextureImage's texture is configured to use
381 * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
382 * default, GL_LINEAR filtering. Specify
383 * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify
384 * |aFlags=OriginBottomLeft| if the image is origin-bottom-left, instead of the
385 * default origin-top-left. Return
386 * nullptr if creating the TextureImage fails.
388 * The returned TextureImage may only be used with this GLContext.
389 * Attempting to use the returned TextureImage after this
390 * GLContext is destroyed will result in undefined (and likely
391 * crashy) behavior.
393 already_AddRefed<TextureImage>
394 CreateTextureImage(GLContext* gl,
395 const gfx::IntSize& aSize,
396 TextureImage::ContentType aContentType,
397 GLenum aWrapMode,
398 TextureImage::Flags aFlags = TextureImage::NoFlags,
399 TextureImage::ImageFormat aImageFormat = gfxImageFormat::Unknown);
401 } // namespace gl
402 } // namespace mozilla
404 #endif /* GLTEXTUREIMAGE_H_ */