summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/Texture2D.h
blob: e64a035f3a448ba6ab2d23ae20e54e988d9467eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#pragma once

#include "Texture.h"
#include "Configuration/UnityConfigure.h"
#include "Runtime/Modules/ExportModules.h"

class ColorRGBAf;
class ColorRGBA32;


class EXPORT_COREMODULE Texture2D: public Texture
{
public:
	// Should be called by MAIN thread in order to upload texture data immediately after texture asset was loaded
	// On some platforms helps to avoid memory peak during level load
	static void IntegrateLoadedImmediately();

protected:

	// See comments at Texture2D.cpp
	struct TextureRepresentation {
		TextureRepresentation();

		UInt8*	data; // data for all image frames
		int		width;
		int		height;
		int		format;
		int		imageSize; // size in bytes of one image frames, including mip levels
	};
	TextureRepresentation	m_TexData;	// original data
	TextureID m_UnscaledTexID;

	static bool s_ScreenReadAllowed;

protected:
	int		m_ImageCount;
	int		m_TextureDimension;

	int		m_glWidth;
	int		m_glHeight;

	int		m_InitFlags;
	bool	m_MipMap;
	bool	m_PowerOfTwo;
	bool    m_TextureUploaded;
	bool    m_UnscaledTextureUploaded;
	bool    m_IsReadable;
	bool	m_ReadAllowed;
	bool	m_IsUnreloadable;

	#if UNITY_EDITOR
	bool	m_EditorDontWriteTextureData;
	bool	m_IgnoreMasterTextureLimit;
	bool	m_AlphaIsTransparency;
	#endif

protected:
	void DestroyTexture ();
	void DeleteGfxTexture ();

	virtual void UploadTexture (bool dontUseSubImage);
	virtual void UnloadFromGfxDevice(bool forceUnloadAll);
	virtual void UploadToGfxDevice();


private:

	void	DestroyTextureRepresentation( TextureRepresentation* rep );
	void	DestroyTextureRepresentations( TextureRepresentation* scaled, TextureRepresentation* padded, bool freeSourceImage=true );

	void	InitTextureRepresentation( TextureRepresentation* rep, int format, const char* tag );
	void	InitTextureRepresentations( TextureRepresentation* scaled, TextureRepresentation* padded );

	void	UpdatePOTStatus();


	void ExtractMipLevel( TextureRepresentation* dst, int frame, int mipLevel, bool checkCompression, bool scaleToSize );
	bool ExtractImageInternal( ImageReference* image, bool scaleToSize, int imageIndex ) const;
	void ExtractCompressedImageInternal( UInt8* dst, int dstWidth, int dstHeight, int imageIndex ) const;

	bool GetImageReferenceInternal (ImageReference* image, int frame, int miplevel) const;

	bool CheckHasPixelData () const;

	MemLabelId GetTextureDataMemoryLabel() const { return ( GetMemoryLabel().label == kMemTextureCacheId ? GetMemoryLabel() : MemLabelId(kMemTextureId, GetMemoryLabel().GetRootHeader()) ); }
public:
	REGISTER_DERIVED_CLASS (Texture2D, Texture)
	DECLARE_OBJECT_SERIALIZE (Texture2D)

	Texture2D (MemLabelId label, ObjectCreationMode mode);
	// ~Texture2D (); declared-by-macro

	virtual bool MainThreadCleanup ();

	virtual void Reset ();
	virtual void AwakeFromLoadThreaded ();
	virtual void AwakeFromLoad (AwakeFromLoadMode awakeMode);

	virtual TextureDimension GetDimension () const { return static_cast<TextureDimension>(m_TextureDimension); }

	virtual int GetGLWidth() const	{ return m_glWidth; }
	virtual int GetGLHeight() const { return m_glHeight; }
	virtual void ApplySettings();

	virtual int GetDataWidth() const;
	virtual int GetDataHeight() const;

	virtual int GetRuntimeMemorySize() const;
	#if ENABLE_PROFILER || UNITY_EDITOR
	virtual int GetStorageMemorySize() const { return m_TexData.imageSize*m_ImageCount; }
	#endif

	virtual TextureID GetUnscaledTextureID() const;
	int CountDataMipmaps () const;
	bool IsNonPowerOfTwo() const { return !m_PowerOfTwo; }

	enum {
		kNoMipmap = 0,
		kMipmapMask = 1 << 0,
		kThreadedInitialize = 1 << 2,
		kOSDrawingCompatible = 1 << 3,
	};
	virtual bool InitTexture (int width, int height, TextureFormat format, int flags=kMipmapMask, int imageCount=1, intptr_t nativeTex=0);

	void   InitTextureInternal (int width, int height, TextureFormat format, int imageSize, UInt8* buffer, int options, int imageCount);
	UInt8* AllocateTextureData (int imageSize, TextureFormat format, bool initMemory = false);
	void   DeallocateTextureData (UInt8* memory);

	virtual bool HasMipMap () const;

	void SetIsReadable (bool readable) { m_IsReadable = readable; }
	bool GetIsReadable () const { return m_IsReadable; }
	void SetIsUnreloadable (bool value) { m_IsUnreloadable = value; }
	bool GetIsUploaded () const { return m_TextureUploaded; }

	#if UNITY_EDITOR
	void SetEditorDontWriteTextureData (bool value) { m_EditorDontWriteTextureData = value; }
	// directly load from an image, used in editor for gizmos/icons
	void SetImage (const ImageReference& image, int flags = kMipmapMask);
	virtual void WarnInstantiateDisallowed ();
	virtual bool IgnoreMasterTextureLimit () const;
	void SetIgnoreMasterTextureLimit (bool ignore);

	bool GetAlphaIsTransparency() const;
	void SetAlphaIsTransparency(bool is);

	virtual TextureFormat GetEditorUITextureFormat () const { return GetTextureFormat(); }

	#endif

	virtual void UpdateImageData ();
	virtual void UpdateImageDataDontTouchMipmap ();

	// Returns the original (may be NPOT) data
	UInt8 *GetRawImageData (int frame = 0) { return m_TexData.data + frame * m_TexData.imageSize; }
	int GetRawImageDataSize () const { return m_TexData.imageSize; }

	bool GetWriteImageReference (ImageReference* image, int frame, int miplevel);

	int GetImageCount () const { return m_ImageCount; }

	virtual bool ExtractImage (ImageReference* image, int imageIndex = 0) const;

	bool ResizeWithFormat (int width, int height, TextureFormat format, int flags);
	bool Resize (int width, int height) { return ResizeWithFormat (width, height, GetTextureFormat(), HasMipMap() ? kMipmapMask : kNoMipmap); }

	int GetTextureFormat () const { return m_TexData.format; }

	void Compress (bool dither);

	virtual void RebuildMipMap ();

	virtual int CountMipmaps () const;

	ColorRGBAf GetPixelBilinear (int image, float u, float v) const;
	ColorRGBAf GetPixel (int image, int x, int y) const;
	void SetPixel (int image, int x, int y, const ColorRGBAf& c);

	// Read pixels. Set reversed when reading into a cubemap
	void ReadPixels (int frame, int left, int bottom, int width, int height, int destX, int destY, bool reversed, bool computeMipMap);

	bool GetPixels (int x, int y, int width, int height, int mipLevel, ColorRGBAf* data, int frame = 0) const;
	void SetPixels( int x, int y, int width, int height, int pixelCount, const ColorRGBAf* pixels, int miplevel, int frame = 0 );


	// always whole mip level, into/from 32 bit RGBA colors
	// GetPixels32 also supports getting pixels from DXT textures.
	// For DXT textures the output width/height must have minimum of 4.
	bool GetPixels32( int mipLevel, ColorRGBA32* data ) const;
	void SetPixels32( int mipLevel, const ColorRGBA32* pixels, const int pixelCount );

	// Encodes to PNG bytes
	bool EncodeToPNG( dynamic_array<UInt8>& outBuffer );

	// Is reading the data from this texture allowed by webplayer security
	void SetReadAllowed (bool allowed) { m_ReadAllowed = allowed; if (!allowed) s_ScreenReadAllowed=false;}
	bool GetReadAllowed () const { return m_ReadAllowed; }

	void Apply(bool updateMipmaps, bool makeNoLongerReadable);

	static bool GetScreenReadAllowed () { return s_ScreenReadAllowed; }


	friend struct TemporaryTextureSerializationRevert;
};

void ConvertTextureEndianessWrite (int format, UInt8* src, UInt8* dst, int size, bool bBigEndianGPU);
void ConvertTextureEndianessRead (int format, UInt8* src, int size);