1//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Texture.h: Defines the abstract gl::Texture class and its concrete derived
8// classes Texture2D and TextureCubeMap. Implements GL texture objects and
9// related functionality. [OpenGL ES 2.0.24] section 3.7 page 63.
10
11#ifndef LIBGLESV2_TEXTURE_H_
12#define LIBGLESV2_TEXTURE_H_
13
14#include <vector>
15
16#define GL_APICALL
17#include <GLES2/gl2.h>
18#include <d3d9.h>
19
20#include "libGLESv2/Renderbuffer.h"
21#include "libGLESv2/RefCountObject.h"
22#include "libGLESv2/utilities.h"
23#include "common/debug.h"
24
25namespace gl
26{
27class Blit;
28
29enum
30{
31    // These are the maximums the implementation can support
32    // The actual GL caps are limited by the device caps
33    // and should be queried from the Context
34    IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
35    IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
36
37    IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15   // 1+log2 of MAX_TEXTURE_SIZE
38};
39
40class Texture : public RefCountObject
41{
42  public:
43    explicit Texture(GLuint id);
44
45    virtual ~Texture();
46
47    virtual GLenum getTarget() const = 0;
48
49    bool setMinFilter(GLenum filter);
50    bool setMagFilter(GLenum filter);
51    bool setWrapS(GLenum wrap);
52    bool setWrapT(GLenum wrap);
53
54    GLenum getMinFilter() const;
55    GLenum getMagFilter() const;
56    GLenum getWrapS() const;
57    GLenum getWrapT() const;
58
59    GLuint getWidth() const;
60    GLuint getHeight() const;
61
62    virtual GLenum getFormat() const = 0;
63    virtual bool isComplete() const = 0;
64    virtual bool isCompressed() const = 0;
65    bool isFloatingPoint() const;
66    bool isRenderableFormat() const;
67
68    D3DFORMAT getD3DFormat() const;
69    IDirect3DBaseTexture9 *getTexture();
70    virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
71
72    virtual void generateMipmaps() = 0;
73    virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) = 0;
74
75    bool isDirty() const;
76
77    static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
78
79  protected:
80    class TextureColorbufferProxy;
81    friend class TextureColorbufferProxy;
82    class TextureColorbufferProxy : public Colorbuffer
83    {
84      public:
85        TextureColorbufferProxy(Texture *texture, GLenum target);
86            // target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
87
88        virtual void addRef() const;
89        virtual void release() const;
90
91        virtual IDirect3DSurface9 *getRenderTarget();
92
93        virtual int getWidth() const;
94        virtual int getHeight() const;
95        virtual GLenum getFormat() const;
96        virtual bool isFloatingPoint() const;
97
98      private:
99        Texture *mTexture;
100        GLenum mTarget;
101    };
102
103    // Helper structure representing a single image layer
104    struct Image
105    {
106        Image();
107        ~Image();
108
109        GLsizei width;
110        GLsizei height;
111        GLenum format;
112
113        bool dirty;
114
115        IDirect3DSurface9 *surface;
116    };
117
118    static D3DFORMAT selectFormat(GLenum format, GLenum type);
119
120    void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
121    bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
122    void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
123    bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
124    void copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
125
126    void needRenderTarget();
127
128    GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
129    GLint creationLevels(GLsizei size, GLint maxlevel) const;
130
131    // The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call.
132    virtual IDirect3DBaseTexture9 *createTexture() = 0;
133    virtual void updateTexture() = 0;
134    virtual IDirect3DBaseTexture9 *convertToRenderTarget() = 0;
135    virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
136
137    virtual bool dirtyImageData() const = 0;
138
139    void dropTexture();
140    void pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable);
141    void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img);
142
143    Blit *getBlitter();
144
145    int levelCount() const;
146
147    bool isRenderable() const;
148
149    unsigned int mWidth;
150    unsigned int mHeight;
151    GLenum mMinFilter;
152    GLenum mMagFilter;
153    GLenum mWrapS;
154    GLenum mWrapT;
155    GLenum mType;
156
157    bool mDirtyMetaData;
158
159  private:
160    DISALLOW_COPY_AND_ASSIGN(Texture);
161
162    void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
163                       GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const;
164
165    void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
166                            size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
167    void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
168                                 size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
169    void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
170                                     size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
171    void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
172                                size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
173    void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
174                                     size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
175    void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
176                                         size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
177    void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
178                                     size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
179    void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
180                                          size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
181    void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
182                                              size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
183    void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
184                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
185    void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
186                             size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
187    void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
188                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
189    void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
190                                   size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
191    void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
192                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
193    void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
194                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
195    void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
196                               size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
197    void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
198                                size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
199    void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
200                                    size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
201    void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
202                           size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
203
204    IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
205
206    bool mDirty;
207    bool mIsRenderable;
208};
209
210class Texture2D : public Texture
211{
212  public:
213    explicit Texture2D(GLuint id);
214
215    ~Texture2D();
216
217    GLenum getTarget() const;
218    GLenum getFormat() const;
219
220    void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
221    void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
222    void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
223    void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
224    void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
225    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
226
227    bool isComplete() const;
228    bool isCompressed() const;
229
230    virtual void generateMipmaps();
231
232    virtual Renderbuffer *getColorbuffer(GLenum target);
233
234  private:
235    DISALLOW_COPY_AND_ASSIGN(Texture2D);
236
237    virtual IDirect3DBaseTexture9 *createTexture();
238    virtual void updateTexture();
239    virtual IDirect3DBaseTexture9 *convertToRenderTarget();
240    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
241
242    virtual bool dirtyImageData() const;
243
244    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
245    void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
246
247    Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
248
249    IDirect3DTexture9 *mTexture;
250
251    BindingPointer<Renderbuffer> mColorbufferProxy;
252};
253
254class TextureCubeMap : public Texture
255{
256  public:
257    explicit TextureCubeMap(GLuint id);
258
259    ~TextureCubeMap();
260
261    GLenum getTarget() const;
262    GLenum getFormat() const;
263
264    void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
265    void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
266    void setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
267    void setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
268    void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
269    void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
270
271    void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
272
273    void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
274    void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
275    void copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
276    void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
277
278    bool isComplete() const;
279    bool isCompressed() const;
280
281    virtual void generateMipmaps();
282
283    virtual Renderbuffer *getColorbuffer(GLenum target);
284
285  private:
286    DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
287
288    virtual IDirect3DBaseTexture9 *createTexture();
289    virtual void updateTexture();
290    virtual IDirect3DBaseTexture9 *convertToRenderTarget();
291    virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
292
293    virtual bool dirtyImageData() const;
294
295    // faceIdentifier is 0-5 or one of the GL_TEXTURE_CUBE_MAP_* enumerants.
296    // Returns NULL if the call underlying Direct3D call fails.
297    IDirect3DSurface9 *getCubeMapSurface(unsigned int faceIdentifier, unsigned int level);
298
299    static unsigned int faceIndex(GLenum face);
300
301    bool isCubeComplete() const;
302
303    void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
304    void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
305    bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width);
306
307    Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
308
309    IDirect3DCubeTexture9 *mTexture;
310
311    BindingPointer<Renderbuffer> mFaceProxies[6];
312};
313}
314
315#endif   // LIBGLESV2_TEXTURE_H_
316