blob: deb2d050a5a9e49799b05b43e5fac2898c6e9b03 [file] [log] [blame]
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00001//
daniel@transgaming.com2b5af7b2012-09-27 17:46:15 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com95a758f2012-07-12 15:17:06 +00003// 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 "common/debug.h"
21#include "common/RefCountObject.h"
22#include "libGLESv2/Renderbuffer.h"
23#include "libGLESv2/utilities.h"
24
25namespace egl
26{
27class Surface;
28}
29
30namespace gl
31{
32class Blit;
33class Framebuffer;
34
35enum
36{
37 // These are the maximums the implementation can support
38 // The actual GL caps are limited by the device caps
39 // and should be queried from the Context
40 IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
41 IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
42
43 IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
44};
45
46class Image
47{
48 public:
49 Image();
50 ~Image();
51
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000052 bool redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000053 void markDirty() {mDirty = true;}
54 void markClean() {mDirty = false;}
55
56 bool isRenderableFormat() const;
57 D3DFORMAT getD3DFormat() const;
58
59 GLsizei getWidth() const {return mWidth;}
60 GLsizei getHeight() const {return mHeight;}
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000061 GLenum getInternalFormat() const {return mInternalFormat;}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000062 bool isDirty() const {return mSurface && mDirty;}
63 IDirect3DSurface9 *getSurface();
64
65 void setManagedSurface(IDirect3DSurface9 *surface);
66 void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
67
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000068 void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000069 GLint unpackAlignment, const void *input);
70
71 void loadAlphaData(GLsizei width, GLsizei height,
72 int inputPitch, const void *input, size_t outputPitch, void *output) const;
73 void loadAlphaDataSSE2(GLsizei width, GLsizei height,
74 int inputPitch, const void *input, size_t outputPitch, void *output) const;
75 void loadAlphaFloatData(GLsizei width, GLsizei height,
76 int inputPitch, const void *input, size_t outputPitch, void *output) const;
77 void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
78 int inputPitch, const void *input, size_t outputPitch, void *output) const;
79 void loadLuminanceData(GLsizei width, GLsizei height,
80 int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
81 void loadLuminanceFloatData(GLsizei width, GLsizei height,
82 int inputPitch, const void *input, size_t outputPitch, void *output) const;
83 void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
84 int inputPitch, const void *input, size_t outputPitch, void *output) const;
85 void loadLuminanceAlphaData(GLsizei width, GLsizei height,
86 int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
87 void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
88 int inputPitch, const void *input, size_t outputPitch, void *output) const;
89 void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
90 int inputPitch, const void *input, size_t outputPitch, void *output) const;
91 void loadRGBUByteData(GLsizei width, GLsizei height,
92 int inputPitch, const void *input, size_t outputPitch, void *output) const;
93 void loadRGB565Data(GLsizei width, GLsizei height,
94 int inputPitch, const void *input, size_t outputPitch, void *output) const;
95 void loadRGBFloatData(GLsizei width, GLsizei height,
96 int inputPitch, const void *input, size_t outputPitch, void *output) const;
97 void loadRGBHalfFloatData(GLsizei width, GLsizei height,
98 int inputPitch, const void *input, size_t outputPitch, void *output) const;
99 void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
100 int inputPitch, const void *input, size_t outputPitch, void *output) const;
101 void loadRGBAUByteData(GLsizei width, GLsizei height,
102 int inputPitch, const void *input, size_t outputPitch, void *output) const;
103 void loadRGBA4444Data(GLsizei width, GLsizei height,
104 int inputPitch, const void *input, size_t outputPitch, void *output) const;
105 void loadRGBA5551Data(GLsizei width, GLsizei height,
106 int inputPitch, const void *input, size_t outputPitch, void *output) const;
107 void loadRGBAFloatData(GLsizei width, GLsizei height,
108 int inputPitch, const void *input, size_t outputPitch, void *output) const;
109 void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
110 int inputPitch, const void *input, size_t outputPitch, void *output) const;
111 void loadBGRAData(GLsizei width, GLsizei height,
112 int inputPitch, const void *input, size_t outputPitch, void *output) const;
113 void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
114 const void *input);
115
116 void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
117
118 private:
119 DISALLOW_COPY_AND_ASSIGN(Image);
120
121 void createSurface();
122
123 HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
124 void unlock();
125
126 GLsizei mWidth;
127 GLsizei mHeight;
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000128 GLint mInternalFormat;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000129
130 bool mDirty;
131
132 D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
133 D3DFORMAT mD3DFormat;
134
135 IDirect3DSurface9 *mSurface;
136};
137
138class TextureStorage
139{
140 public:
141 explicit TextureStorage(DWORD usage);
142
143 virtual ~TextureStorage();
144
145 bool isRenderTarget() const;
146 bool isManaged() const;
147 D3DPOOL getPool() const;
148 DWORD getUsage() const;
149 unsigned int getTextureSerial() const;
150 virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
jbauman@chromium.org68715282012-07-12 23:28:41 +0000151 int getLodOffset() const;
152
153 protected:
154 int mLodOffset;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000155
156 private:
157 DISALLOW_COPY_AND_ASSIGN(TextureStorage);
158
159 const DWORD mD3DUsage;
160 const D3DPOOL mD3DPool;
161
162 const unsigned int mTextureSerial;
163 static unsigned int issueTextureSerial();
164
165 static unsigned int mCurrentTextureSerial;
166};
167
168class Texture : public RefCountObject
169{
170 public:
171 explicit Texture(GLuint id);
172
173 virtual ~Texture();
174
175 virtual void addProxyRef(const Renderbuffer *proxy) = 0;
176 virtual void releaseProxy(const Renderbuffer *proxy) = 0;
177
178 virtual GLenum getTarget() const = 0;
179
180 bool setMinFilter(GLenum filter);
181 bool setMagFilter(GLenum filter);
182 bool setWrapS(GLenum wrap);
183 bool setWrapT(GLenum wrap);
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000184 bool setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000185 bool setUsage(GLenum usage);
186
187 GLenum getMinFilter() const;
188 GLenum getMagFilter() const;
189 GLenum getWrapS() const;
190 GLenum getWrapT() const;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000191 float getMaxAnisotropy() const;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000192 GLenum getUsage() const;
daniel@transgaming.comca9a3c82012-10-26 18:55:07 +0000193 bool isMipmapFiltered() const;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000194
195 virtual bool isSamplerComplete() const = 0;
196
197 IDirect3DBaseTexture9 *getTexture();
198 virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
199
200 virtual void generateMipmaps() = 0;
201 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
202
203 bool hasDirtyParameters() const;
204 bool hasDirtyImages() const;
205 void resetDirty();
206 unsigned int getTextureSerial();
207 unsigned int getRenderTargetSerial(GLenum target);
208
209 bool isImmutable() const;
jbauman@chromium.org68715282012-07-12 23:28:41 +0000210 int getLodOffset();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000211
212 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.
213
214 protected:
215 void setImage(GLint unpackAlignment, const void *pixels, Image *image);
216 bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
217 void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
218 bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
219
220 GLint creationLevels(GLsizei width, GLsizei height) const;
221 GLint creationLevels(GLsizei size) const;
222
223 virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
224 virtual void createTexture() = 0;
225 virtual void updateTexture() = 0;
226 virtual void convertToRenderTarget() = 0;
227 virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
228
jbauman@chromium.org6bc4a142012-09-06 21:28:30 +0000229 int levelCount();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000230
231 static Blit *getBlitter();
232 static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
233
234 GLenum mMinFilter;
235 GLenum mMagFilter;
236 GLenum mWrapS;
237 GLenum mWrapT;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000238 float mMaxAnisotropy;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000239 bool mDirtyParameters;
240 GLenum mUsage;
241
242 bool mDirtyImages;
243
244 bool mImmutable;
245
246 private:
247 DISALLOW_COPY_AND_ASSIGN(Texture);
248
249 virtual TextureStorage *getStorage(bool renderTarget) = 0;
250};
251
252class TextureStorage2D : public TextureStorage
253{
254 public:
255 explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
256 TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
257
258 virtual ~TextureStorage2D();
259
daniel@transgaming.com2b5af7b2012-09-27 17:46:15 +0000260 IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000261 IDirect3DBaseTexture9 *getBaseTexture() const;
262
263 virtual unsigned int getRenderTargetSerial(GLenum target) const;
264
265 private:
266 DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
267
268 IDirect3DTexture9 *mTexture;
269 const unsigned int mRenderTargetSerial;
270};
271
272class Texture2D : public Texture
273{
274 public:
275 explicit Texture2D(GLuint id);
276
277 ~Texture2D();
278
279 void addProxyRef(const Renderbuffer *proxy);
280 void releaseProxy(const Renderbuffer *proxy);
281
282 virtual GLenum getTarget() const;
283
284 GLsizei getWidth(GLint level) const;
285 GLsizei getHeight(GLint level) const;
286 GLenum getInternalFormat(GLint level) const;
287 D3DFORMAT getD3DFormat(GLint level) const;
288 bool isCompressed(GLint level) const;
289 bool isDepth(GLint level) const;
290
291 void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
292 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
293 void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
294 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
295 void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
296 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
297 void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
298
299 virtual bool isSamplerComplete() const;
300 virtual void bindTexImage(egl::Surface *surface);
301 virtual void releaseTexImage();
302
303 virtual void generateMipmaps();
304
305 virtual Renderbuffer *getRenderbuffer(GLenum target);
306
307 protected:
308 friend class RenderbufferTexture2D;
309 virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
310 virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
311
312 private:
313 DISALLOW_COPY_AND_ASSIGN(Texture2D);
314
315 virtual IDirect3DBaseTexture9 *getBaseTexture() const;
316 virtual void createTexture();
317 virtual void updateTexture();
318 virtual void convertToRenderTarget();
319 virtual TextureStorage *getStorage(bool renderTarget);
320
321 bool isMipmapComplete() const;
322
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000323 void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000324 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
325
326 Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
327
328 TextureStorage2D *mTexStorage;
329 egl::Surface *mSurface;
330
331 // A specific internal reference count is kept for colorbuffer proxy references,
332 // because, as the renderbuffer acting as proxy will maintain a binding pointer
333 // back to this texture, there would be a circular reference if we used a binding
334 // pointer here. This reference count will cause the pointer to be set to NULL if
335 // the count drops to zero, but will not cause deletion of the Renderbuffer.
336 Renderbuffer *mColorbufferProxy;
337 unsigned int mProxyRefs;
338};
339
340class TextureStorageCubeMap : public TextureStorage
341{
342 public:
343 TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
344
345 virtual ~TextureStorageCubeMap();
346
daniel@transgaming.com2b5af7b2012-09-27 17:46:15 +0000347 IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000348 IDirect3DBaseTexture9 *getBaseTexture() const;
349
350 virtual unsigned int getRenderTargetSerial(GLenum target) const;
351
352 private:
353 DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
354
355 IDirect3DCubeTexture9 *mTexture;
356 const unsigned int mFirstRenderTargetSerial;
357};
358
359class TextureCubeMap : public Texture
360{
361 public:
362 explicit TextureCubeMap(GLuint id);
363
364 ~TextureCubeMap();
365
366 void addProxyRef(const Renderbuffer *proxy);
367 void releaseProxy(const Renderbuffer *proxy);
368
369 virtual GLenum getTarget() const;
370
371 GLsizei getWidth(GLenum target, GLint level) const;
372 GLsizei getHeight(GLenum target, GLint level) const;
373 GLenum getInternalFormat(GLenum target, GLint level) const;
374 D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
375 bool isCompressed(GLenum target, GLint level) const;
376
377 void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
378 void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
379 void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
380 void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
381 void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
382 void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
383
384 void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
385
386 void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
387 void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
388 void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
389 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
390 void storage(GLsizei levels, GLenum internalformat, GLsizei size);
391
392 virtual bool isSamplerComplete() const;
393
394 virtual void generateMipmaps();
395
396 virtual Renderbuffer *getRenderbuffer(GLenum target);
397
398 static unsigned int faceIndex(GLenum face);
399
400 protected:
401 friend class RenderbufferTextureCubeMap;
402 virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
403
404 private:
405 DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
406
407 virtual IDirect3DBaseTexture9 *getBaseTexture() const;
408 virtual void createTexture();
409 virtual void updateTexture();
410 virtual void convertToRenderTarget();
411 virtual TextureStorage *getStorage(bool renderTarget);
412
413 bool isCubeComplete() const;
414 bool isMipmapCubeComplete() const;
415
416 void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
417 void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000418 void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000419
420 Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
421
422 TextureStorageCubeMap *mTexStorage;
423
424 // A specific internal reference count is kept for colorbuffer proxy references,
425 // because, as the renderbuffer acting as proxy will maintain a binding pointer
426 // back to this texture, there would be a circular reference if we used a binding
427 // pointer here. This reference count will cause the pointer to be set to NULL if
428 // the count drops to zero, but will not cause deletion of the Renderbuffer.
429 Renderbuffer *mFaceProxies[6];
430 unsigned int *mFaceProxyRefs[6];
431};
432}
433
jbauman@chromium.org68715282012-07-12 23:28:41 +0000434#endif // LIBGLESV2_TEXTURE_H_