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