Support for ASTC compressed textures wrapped in KTX files
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / texture.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/render/gl-resources/texture.h>
20
21 // EXTERNAL INCLUDES
22 #include <math.h>
23 #include <memory.h>
24
25 // INTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/render/gl-resources/context.h>
28 #include <dali/internal/common/image-sampler.h>
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 // These match the GL specification
40 const GLint SYSTEM_MINIFY_DEFAULT  = GL_NEAREST_MIPMAP_LINEAR;
41 const GLint SYSTEM_MAGNIFY_DEFAULT = GL_LINEAR;
42 const GLint SYSTEM_WRAP_DEFAULT  = GL_CLAMP_TO_EDGE;
43
44 // These are the Dali defaults
45 const GLint DALI_MINIFY_DEFAULT  = GL_LINEAR;
46 const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
47
48 } // namespace
49
50 /**
51  * @brief Convert a FilterMode to it's corresponding GL type.
52  *
53  * @param[in] filterMode The FilterMode type.
54  * @param[in] defaultfilterMode The filter mode to use if filterMode is DEFAULT.
55  * @param[in] defaultSystemFilterMode The filter mode to use if filterMode is NONE.
56  * @return Return the equivalent GL type.
57  */
58 GLint FilterModeToGL( FilterMode::Type filterMode, GLint defaultfilterMode, GLint defaultSystemFilterMode )
59 {
60   switch( filterMode )
61   {
62     case FilterMode::NEAREST:
63     {
64       return GL_NEAREST;
65     }
66     case FilterMode::LINEAR:
67     {
68       return GL_LINEAR;
69     }
70     case FilterMode::NONE:
71     {
72       return defaultSystemFilterMode;
73     }
74     case FilterMode::DEFAULT:
75     {
76       return defaultfilterMode;
77     }
78   }
79
80   return GL_LINEAR;
81 }
82
83 GLint WrapModeToGL( WrapMode::Type wrapMode, GLint defaultWrapMode )
84 {
85   switch( wrapMode )
86   {
87     case WrapMode::DEFAULT:
88     {
89       return defaultWrapMode;
90     }
91     case WrapMode::CLAMP_TO_EDGE:
92     {
93       return GL_CLAMP_TO_EDGE;
94     }
95     case WrapMode::REPEAT:
96     {
97       return GL_REPEAT;
98     }
99     case WrapMode::MIRRORED_REPEAT:
100     {
101       return GL_MIRRORED_REPEAT;
102     }
103   }
104
105   return defaultWrapMode;
106 }
107
108 using Dali::Internal::Vertex2D;
109
110 using namespace Dali::Pixel;
111
112 Texture::Texture(Context&      context,
113                  unsigned int  width,
114                  unsigned int  height,
115                  unsigned int  imageWidth,
116                  unsigned int  imageHeight)
117 : mContext(context),
118   mId(0),
119   mSamplerBitfield( 0 ),
120   mWidth(width),
121   mHeight(height),
122   mImageWidth(imageWidth),
123   mImageHeight(imageHeight)
124 {
125 }
126
127 Texture::Texture(Context&      context,
128                  unsigned int  width,
129                  unsigned int  height)
130 : mContext(context),
131   mId(0),
132   mSamplerBitfield( 0 ),
133   mWidth(width),
134   mHeight(height),
135   mImageWidth(width),
136   mImageHeight(height)
137 {
138 }
139
140 Texture::~Texture()
141 {
142   // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed
143   // on the render thread. (And avoiding a potentially problematic virtual call in the destructor)
144 }
145
146 void Texture::SetTextureId(GLuint id)
147 {
148   mId=id;
149 }
150
151 void Texture::Update(Integration::Bitmap* bitmap)
152 {
153   DALI_ASSERT_DEBUG( "Updating incorrect texture type" == NULL );
154 }
155
156 void Texture::UpdateArea( const RectArea& area )
157 {
158   DALI_ASSERT_DEBUG( "Updating incorrect texture type" == NULL );
159 }
160
161 bool Texture::UpdateOnCreate()
162 {
163   return false;
164 }
165
166 bool Texture::Bind(GLenum target, TextureUnit textureunit )
167 {
168   // This is the only supported type at the moment
169   DALI_ASSERT_DEBUG( target == GL_TEXTURE_2D );
170   bool created = false;
171
172   if( mId == 0 )
173   {
174     if( CreateGlTexture() )
175     {
176       created = true;
177     }
178   }
179
180   // Bind the texture id
181   mContext.BindTextureForUnit(textureunit, mId );
182
183   return created;
184 }
185
186 void Texture::GlContextDestroyed()
187 {
188   // texture is gone
189   mId = 0;
190   // reset sampler state as well
191   mSamplerBitfield = 0;
192 }
193
194 void Texture::GlCleanup()
195 {
196   // delete the gl texture
197   if (mId != 0)
198   {
199     mContext.DeleteTextures(1,&mId);
200     mId = 0;
201   }
202 }
203
204 unsigned int Texture::GetWidth() const
205 {
206   return mWidth;
207 }
208
209 unsigned int Texture::GetHeight() const
210 {
211   return mHeight;
212 }
213
214 void Texture::ApplyFilterModeParameter( TextureUnit unit, GLint filterType, FilterMode::Type currentFilterMode, FilterMode::Type newFilterMode, GLint daliDefault, GLint systemDefault )
215 {
216   GLint newFilterModeGL = FilterModeToGL( newFilterMode, daliDefault, systemDefault );
217   GLint currentFilterModeGL = FilterModeToGL( currentFilterMode, daliDefault, systemDefault );
218
219   if( newFilterModeGL != currentFilterModeGL )
220   {
221     mContext.ActiveTexture( unit );
222     mContext.TexParameteri( GL_TEXTURE_2D, filterType, newFilterModeGL );
223   }
224 }
225
226 void Texture::ApplyWrapModeParameter( TextureUnit unit, GLint wrapType, WrapMode::Type currentWrapMode, WrapMode::Type newWrapMode )
227 {
228   GLint newWrapModeGL = WrapModeToGL( newWrapMode, SYSTEM_WRAP_DEFAULT );
229   GLint currentWrapModeGL = WrapModeToGL( currentWrapMode, SYSTEM_WRAP_DEFAULT );
230
231   if( newWrapModeGL != currentWrapModeGL )
232   {
233     mContext.ActiveTexture( unit );
234     mContext.TexParameteri( GL_TEXTURE_2D, wrapType, newWrapModeGL );
235   }
236 }
237
238 void Texture::ApplySampler( TextureUnit unit, unsigned int samplerBitfield )
239 {
240   if( mSamplerBitfield != samplerBitfield && mId != 0 )
241   {
242     ApplyFilterModeParameter( unit,
243                            GL_TEXTURE_MIN_FILTER,
244                            ImageSampler::GetMinifyFilterMode( mSamplerBitfield ),
245                            ImageSampler::GetMinifyFilterMode( samplerBitfield ),
246                            DALI_MINIFY_DEFAULT,
247                            SYSTEM_MINIFY_DEFAULT );
248
249     ApplyFilterModeParameter( unit,
250                               GL_TEXTURE_MAG_FILTER,
251                               ImageSampler::GetMagnifyFilterMode( mSamplerBitfield ),
252                               ImageSampler::GetMagnifyFilterMode( samplerBitfield ),
253                               DALI_MAGNIFY_DEFAULT,
254                               SYSTEM_MAGNIFY_DEFAULT );
255
256     ApplyWrapModeParameter( unit,
257                             GL_TEXTURE_WRAP_S,
258                             ImageSampler::GetUWrapMode( mSamplerBitfield ),
259                             ImageSampler::GetUWrapMode( samplerBitfield ));
260
261     ApplyWrapModeParameter( unit,
262                             GL_TEXTURE_WRAP_T,
263                             ImageSampler::GetVWrapMode( mSamplerBitfield ),
264                             ImageSampler::GetVWrapMode( samplerBitfield ));
265
266
267
268     mSamplerBitfield = samplerBitfield;
269   }
270 }
271
272 } // namespace Internal
273
274 } // namespace Dali