blob: 27f2d756b93a567bdfe5d99aad881e10e7bd1c0c [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
daniel@transgaming.comebf139f2012-10-31 18:07:32 +000046struct SamplerState
47{
48 GLenum minFilter;
49 GLenum magFilter;
50 GLenum wrapS;
51 GLenum wrapT;
52 float maxAnisotropy;
53 int lodOffset;
54};
55
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000056class Image
57{
58 public:
59 Image();
60 ~Image();
61
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000062 bool redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000063 void markDirty() {mDirty = true;}
64 void markClean() {mDirty = false;}
65
66 bool isRenderableFormat() const;
67 D3DFORMAT getD3DFormat() const;
68
69 GLsizei getWidth() const {return mWidth;}
70 GLsizei getHeight() const {return mHeight;}
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000071 GLenum getInternalFormat() const {return mInternalFormat;}
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000072 bool isDirty() const {return mSurface && mDirty;}
73 IDirect3DSurface9 *getSurface();
74
75 void setManagedSurface(IDirect3DSurface9 *surface);
76 void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
77
daniel@transgaming.com6452adf2012-10-17 18:22:35 +000078 void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
daniel@transgaming.com95a758f2012-07-12 15:17:06 +000079 GLint unpackAlignment, const void *input);
80
81 void loadAlphaData(GLsizei width, GLsizei height,
82 int inputPitch, const void *input, size_t outputPitch, void *output) const;
83 void loadAlphaDataSSE2(GLsizei width, GLsizei height,
84 int inputPitch, const void *input, size_t outputPitch, void *output) const;
85 void loadAlphaFloatData(GLsizei width, GLsizei height,
86 int inputPitch, const void *input, size_t outputPitch, void *output) const;
87 void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
88 int inputPitch, const void *input, size_t outputPitch, void *output) const;
89 void loadLuminanceData(GLsizei width, GLsizei height,
90 int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
91 void loadLuminanceFloatData(GLsizei width, GLsizei height,
92 int inputPitch, const void *input, size_t outputPitch, void *output) const;
93 void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
94 int inputPitch, const void *input, size_t outputPitch, void *output) const;
95 void loadLuminanceAlphaData(GLsizei width, GLsizei height,
96 int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
97 void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
98 int inputPitch, const void *input, size_t outputPitch, void *output) const;
99 void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
100 int inputPitch, const void *input, size_t outputPitch, void *output) const;
101 void loadRGBUByteData(GLsizei width, GLsizei height,
102 int inputPitch, const void *input, size_t outputPitch, void *output) const;
103 void loadRGB565Data(GLsizei width, GLsizei height,
104 int inputPitch, const void *input, size_t outputPitch, void *output) const;
105 void loadRGBFloatData(GLsizei width, GLsizei height,
106 int inputPitch, const void *input, size_t outputPitch, void *output) const;
107 void loadRGBHalfFloatData(GLsizei width, GLsizei height,
108 int inputPitch, const void *input, size_t outputPitch, void *output) const;
109 void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
110 int inputPitch, const void *input, size_t outputPitch, void *output) const;
111 void loadRGBAUByteData(GLsizei width, GLsizei height,
112 int inputPitch, const void *input, size_t outputPitch, void *output) const;
113 void loadRGBA4444Data(GLsizei width, GLsizei height,
114 int inputPitch, const void *input, size_t outputPitch, void *output) const;
115 void loadRGBA5551Data(GLsizei width, GLsizei height,
116 int inputPitch, const void *input, size_t outputPitch, void *output) const;
117 void loadRGBAFloatData(GLsizei width, GLsizei height,
118 int inputPitch, const void *input, size_t outputPitch, void *output) const;
119 void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
120 int inputPitch, const void *input, size_t outputPitch, void *output) const;
121 void loadBGRAData(GLsizei width, GLsizei height,
122 int inputPitch, const void *input, size_t outputPitch, void *output) const;
123 void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
124 const void *input);
125
126 void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
127
128 private:
129 DISALLOW_COPY_AND_ASSIGN(Image);
130
131 void createSurface();
132
133 HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
134 void unlock();
135
136 GLsizei mWidth;
137 GLsizei mHeight;
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000138 GLint mInternalFormat;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000139
140 bool mDirty;
141
142 D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
143 D3DFORMAT mD3DFormat;
144
145 IDirect3DSurface9 *mSurface;
146};
147
148class TextureStorage
149{
150 public:
151 explicit TextureStorage(DWORD usage);
152
153 virtual ~TextureStorage();
154
155 bool isRenderTarget() const;
156 bool isManaged() const;
157 D3DPOOL getPool() const;
158 DWORD getUsage() const;
159 unsigned int getTextureSerial() const;
160 virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
jbauman@chromium.org68715282012-07-12 23:28:41 +0000161 int getLodOffset() const;
162
163 protected:
164 int mLodOffset;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000165
166 private:
167 DISALLOW_COPY_AND_ASSIGN(TextureStorage);
168
169 const DWORD mD3DUsage;
170 const D3DPOOL mD3DPool;
171
172 const unsigned int mTextureSerial;
173 static unsigned int issueTextureSerial();
174
175 static unsigned int mCurrentTextureSerial;
176};
177
178class Texture : public RefCountObject
179{
180 public:
181 explicit Texture(GLuint id);
182
183 virtual ~Texture();
184
185 virtual void addProxyRef(const Renderbuffer *proxy) = 0;
186 virtual void releaseProxy(const Renderbuffer *proxy) = 0;
187
188 virtual GLenum getTarget() const = 0;
189
190 bool setMinFilter(GLenum filter);
191 bool setMagFilter(GLenum filter);
192 bool setWrapS(GLenum wrap);
193 bool setWrapT(GLenum wrap);
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000194 bool setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000195 bool setUsage(GLenum usage);
196
197 GLenum getMinFilter() const;
198 GLenum getMagFilter() const;
199 GLenum getWrapS() const;
200 GLenum getWrapT() const;
daniel@transgaming.com07ab8412012-07-12 15:17:09 +0000201 float getMaxAnisotropy() const;
daniel@transgaming.comebf139f2012-10-31 18:07:32 +0000202 int getLodOffset();
203 void getSamplerState(SamplerState *sampler);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000204 GLenum getUsage() const;
daniel@transgaming.comca9a3c82012-10-26 18:55:07 +0000205 bool isMipmapFiltered() const;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000206
207 virtual bool isSamplerComplete() const = 0;
208
209 IDirect3DBaseTexture9 *getTexture();
210 virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
211
212 virtual void generateMipmaps() = 0;
213 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
214
215 bool hasDirtyParameters() const;
216 bool hasDirtyImages() const;
217 void resetDirty();
218 unsigned int getTextureSerial();
219 unsigned int getRenderTargetSerial(GLenum target);
220
221 bool isImmutable() const;
222
223 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.
224
225 protected:
226 void setImage(GLint unpackAlignment, const void *pixels, Image *image);
227 bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
228 void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
229 bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
230
231 GLint creationLevels(GLsizei width, GLsizei height) const;
232 GLint creationLevels(GLsizei size) const;
233
234 virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
235 virtual void createTexture() = 0;
236 virtual void updateTexture() = 0;
237 virtual void convertToRenderTarget() = 0;
238 virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
239
jbauman@chromium.org6bc4a142012-09-06 21:28:30 +0000240 int levelCount();
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000241
242 static Blit *getBlitter();
243 static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
244
daniel@transgaming.comebf139f2012-10-31 18:07:32 +0000245 SamplerState mSamplerState;
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000246 bool mDirtyParameters;
247 GLenum mUsage;
248
249 bool mDirtyImages;
250
251 bool mImmutable;
252
253 private:
254 DISALLOW_COPY_AND_ASSIGN(Texture);
255
256 virtual TextureStorage *getStorage(bool renderTarget) = 0;
257};
258
259class TextureStorage2D : public TextureStorage
260{
261 public:
262 explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
263 TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
264
265 virtual ~TextureStorage2D();
266
daniel@transgaming.com2b5af7b2012-09-27 17:46:15 +0000267 IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000268 IDirect3DBaseTexture9 *getBaseTexture() const;
269
270 virtual unsigned int getRenderTargetSerial(GLenum target) const;
271
272 private:
273 DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
274
275 IDirect3DTexture9 *mTexture;
276 const unsigned int mRenderTargetSerial;
277};
278
279class Texture2D : public Texture
280{
281 public:
282 explicit Texture2D(GLuint id);
283
284 ~Texture2D();
285
286 void addProxyRef(const Renderbuffer *proxy);
287 void releaseProxy(const Renderbuffer *proxy);
288
289 virtual GLenum getTarget() const;
290
291 GLsizei getWidth(GLint level) const;
292 GLsizei getHeight(GLint level) const;
293 GLenum getInternalFormat(GLint level) const;
294 D3DFORMAT getD3DFormat(GLint level) const;
295 bool isCompressed(GLint level) const;
296 bool isDepth(GLint level) const;
297
298 void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
299 void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
300 void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
301 void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
302 void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
303 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
304 void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
305
306 virtual bool isSamplerComplete() const;
307 virtual void bindTexImage(egl::Surface *surface);
308 virtual void releaseTexImage();
309
310 virtual void generateMipmaps();
311
312 virtual Renderbuffer *getRenderbuffer(GLenum target);
313
314 protected:
315 friend class RenderbufferTexture2D;
316 virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
317 virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
318
319 private:
320 DISALLOW_COPY_AND_ASSIGN(Texture2D);
321
322 virtual IDirect3DBaseTexture9 *getBaseTexture() const;
323 virtual void createTexture();
324 virtual void updateTexture();
325 virtual void convertToRenderTarget();
326 virtual TextureStorage *getStorage(bool renderTarget);
327
328 bool isMipmapComplete() const;
329
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000330 void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000331 void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
332
333 Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
334
335 TextureStorage2D *mTexStorage;
336 egl::Surface *mSurface;
337
338 // A specific internal reference count is kept for colorbuffer proxy references,
339 // because, as the renderbuffer acting as proxy will maintain a binding pointer
340 // back to this texture, there would be a circular reference if we used a binding
341 // pointer here. This reference count will cause the pointer to be set to NULL if
342 // the count drops to zero, but will not cause deletion of the Renderbuffer.
343 Renderbuffer *mColorbufferProxy;
344 unsigned int mProxyRefs;
345};
346
347class TextureStorageCubeMap : public TextureStorage
348{
349 public:
350 TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
351
352 virtual ~TextureStorageCubeMap();
353
daniel@transgaming.com2b5af7b2012-09-27 17:46:15 +0000354 IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000355 IDirect3DBaseTexture9 *getBaseTexture() const;
356
357 virtual unsigned int getRenderTargetSerial(GLenum target) const;
358
359 private:
360 DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
361
362 IDirect3DCubeTexture9 *mTexture;
363 const unsigned int mFirstRenderTargetSerial;
364};
365
366class TextureCubeMap : public Texture
367{
368 public:
369 explicit TextureCubeMap(GLuint id);
370
371 ~TextureCubeMap();
372
373 void addProxyRef(const Renderbuffer *proxy);
374 void releaseProxy(const Renderbuffer *proxy);
375
376 virtual GLenum getTarget() const;
377
378 GLsizei getWidth(GLenum target, GLint level) const;
379 GLsizei getHeight(GLenum target, GLint level) const;
380 GLenum getInternalFormat(GLenum target, GLint level) const;
381 D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
382 bool isCompressed(GLenum target, GLint level) const;
383
384 void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
385 void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
386 void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
387 void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
388 void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
389 void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
390
391 void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
392
393 void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
394 void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
395 void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
396 virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
397 void storage(GLsizei levels, GLenum internalformat, GLsizei size);
398
399 virtual bool isSamplerComplete() const;
400
401 virtual void generateMipmaps();
402
403 virtual Renderbuffer *getRenderbuffer(GLenum target);
404
405 static unsigned int faceIndex(GLenum face);
406
407 protected:
408 friend class RenderbufferTextureCubeMap;
409 virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
410
411 private:
412 DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
413
414 virtual IDirect3DBaseTexture9 *getBaseTexture() const;
415 virtual void createTexture();
416 virtual void updateTexture();
417 virtual void convertToRenderTarget();
418 virtual TextureStorage *getStorage(bool renderTarget);
419
420 bool isCubeComplete() const;
421 bool isMipmapCubeComplete() const;
422
423 void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
424 void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
daniel@transgaming.com6452adf2012-10-17 18:22:35 +0000425 void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height);
daniel@transgaming.com95a758f2012-07-12 15:17:06 +0000426
427 Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
428
429 TextureStorageCubeMap *mTexStorage;
430
431 // A specific internal reference count is kept for colorbuffer proxy references,
432 // because, as the renderbuffer acting as proxy will maintain a binding pointer
433 // back to this texture, there would be a circular reference if we used a binding
434 // pointer here. This reference count will cause the pointer to be set to NULL if
435 // the count drops to zero, but will not cause deletion of the Renderbuffer.
436 Renderbuffer *mFaceProxies[6];
437 unsigned int *mFaceProxyRefs[6];
438};
439}
440
jbauman@chromium.org68715282012-07-12 23:28:41 +0000441#endif // LIBGLESV2_TEXTURE_H_