Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/gl/GLTextureImage.h
Line
Count
Source (jump to first uncovered line)
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
    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
0
    }
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
    virtual void SetIterationCallback(BigImageIterationCallback aCallback,
82
0
                                      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
0
    }
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
0
    }
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
    virtual already_AddRefed<gfxASurface> GetBackingSurface()
133
0
    { return nullptr; }
134
135
136
    gfx::IntSize GetSize() const;
137
0
    ContentType GetContentType() const { return mContentType; }
138
    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) override;
198
199
    virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) override;
200
0
    virtual GLuint GetTextureID() override { return mTexture; }
201
202
0
    virtual void MarkValid() override { mTextureState = Valid; }
203
204
    virtual void Resize(const gfx::IntSize& aSize) override;
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) override;
229
    virtual uint32_t GetTileCount() override;
230
    virtual void BeginBigImageIteration() override;
231
    virtual bool NextTile() override;
232
    virtual void SetIterationCallback(BigImageIterationCallback aCallback,
233
                                      void* aCallbackData) override;
234
    virtual gfx::IntRect GetTileRect() override;
235
0
    virtual GLuint GetTextureID() override {
236
0
        return mImages[mCurrentImage]->GetTextureID();
237
0
    }
238
    virtual bool DirectUpdate(gfx::DataSourceSurface* aSurf, const nsIntRegion& aRegion, const gfx::IntPoint& aFrom = gfx::IntPoint(0,0)) override;
239
    virtual void BindTexture(GLenum) override;
240
241
protected:
242
    virtual gfx::IntRect GetSrcTileRect() override;
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_ */