ed250591eb8522ba2ed0c942cdb07d7326647037
[platform/core/uifw/dali-core.git] / dali / internal / render / gl-resources / texture.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/render/gl-resources/texture.h>
19
20 // EXTERNAL INCLUDES
21 #include <math.h>
22 #include <memory.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/render/common/vertex.h>
27 #include <dali/internal/render/gl-resources/context.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 using Dali::Internal::Vertex2D;
36 using Dali::Internal::Vertex3D;
37
38 using namespace Dali::Pixel;
39
40 Texture::Texture(Context&      context,
41                  unsigned int  width,
42                  unsigned int  height,
43                  unsigned int  imageWidth,
44                  unsigned int  imageHeight,
45                  Pixel::Format pixelFormat)
46 : mContext(context),
47   mId(0),
48   mWidth(width),
49   mHeight(height),
50   mImageWidth(imageWidth),
51   mImageHeight(imageHeight),
52   mPixelFormat(pixelFormat),
53   mDiscarded(false)
54 {
55   mContext.AddObserver(*this);
56 }
57
58 Texture::~Texture()
59 {
60   mContext.RemoveObserver(*this);
61   // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed
62   // on the render thread. (And avoiding a potentially problematic virtual call in the destructor)
63 }
64
65 void Texture::SetTextureId(GLuint id)
66 {
67   mId=id;
68 }
69
70 void Texture::Update(Integration::Bitmap* bitmap)
71 {
72   DALI_ASSERT_DEBUG( "Updating incorrect texture type" == NULL );
73 }
74
75 void Texture::UpdateArea( const RectArea& area )
76 {
77   DALI_ASSERT_DEBUG( "Updating incorrect texture type" == NULL );
78 }
79
80 bool Texture::UpdateOnCreate()
81 {
82   return false;
83 }
84
85 bool Texture::Bind(GLenum target, GLenum textureunit )
86 {
87   // This is the only supported type at the moment
88   DALI_ASSERT_DEBUG( target == GL_TEXTURE_2D );
89   bool created = false;
90
91   if( mId == 0 )
92   {
93     if( CreateGlTexture() )
94     {
95       created = true;
96     }
97   }
98
99   // Bind the texture id
100   mContext.ActiveTexture(textureunit);
101   mContext.Bind2dTexture(mId);
102
103   return created;
104 }
105
106 void Texture::GlCleanup()
107 {
108   // otherwise, delete the gl texture
109   if (mId != 0)
110   {
111     mContext.DeleteTextures(1,&mId);
112     DALI_LOG_RESOURCE("[DELTEXTURE] Freed image data memory for Texture %u - (%dx%d)\n",
113                       mId, mWidth, mHeight);
114     mId = 0;
115   }
116 }
117
118 void Texture::MapUV(unsigned int numVerts,Vertex2D *verts, const PixelArea* pixelArea)
119 {
120   MapUV(numVerts, (float*)(&verts->mU), sizeof(Vertex2D)/sizeof(float), pixelArea);
121 }
122
123 void Texture::MapUV(unsigned int numVerts,Vertex3D *verts, const PixelArea* pixelArea)
124 {
125   MapUV(numVerts, (float*)(&verts->mU), sizeof(Vertex3D)/sizeof(float), pixelArea);
126 }
127
128 void Texture::MapUV(unsigned int numVerts, float* verts, unsigned int stride, const PixelArea* pixelArea)
129 {
130   UvRect uv;
131
132   GetTextureCoordinates(uv, pixelArea);
133
134   float uScale = fabsf(uv.u2 - uv.u0);
135   float vScale = fabsf(uv.v2 - uv.v0);
136
137   for (unsigned int i = 0; i < numVerts; ++i)
138   {
139     verts[0] = uv.u0 + verts[0] * uScale;
140     verts[1] = uv.v0 + verts[1] * vScale;
141     verts += stride;
142   }
143 }
144
145 unsigned int Texture::GetWidth() const
146 {
147   return mWidth;
148 }
149
150 unsigned int Texture::GetHeight() const
151 {
152   return mHeight;
153 }
154
155 Pixel::Format Texture::GetPixelFormat() const
156 {
157   return mPixelFormat;
158 }
159
160 /*
161  * When an OpenGL context is created and made active we don't
162  * do anything, because we use lazy binding.
163  * This means when a texture is required that's when it's loaded
164  * into OpenGL.
165  */
166 void Texture::GlContextCreated()
167 {
168 }
169
170 /*
171  * From Context::Observer, called just before the OpenGL context is destroyed.
172  */
173 void Texture::GlContextToBeDestroyed()
174 {
175   GlCleanup();
176 }
177
178 void Texture::GetTextureCoordinates(UvRect& uv, const PixelArea* pixelArea)
179 {
180   if( pixelArea == NULL )
181   {
182      GetDefaultTextureCoordinates(uv);
183      return;
184   }
185
186   // pre-calulate the normalized values
187
188   const float uScale = 1.0f / float(mWidth);
189   const float vScale = 1.0f / float(mHeight);
190   const float x = uScale * float(pixelArea->x);
191   const float y = vScale * float(pixelArea->y);
192   const float width  = uScale * float(pixelArea->width);
193   const float height = vScale * float(pixelArea->height);
194
195
196   // bottom left
197   uv.u0 = x;
198   uv.v0 = y;
199
200   // top right
201   uv.u2 = x + width;
202   uv.v2 = y + height;
203
204 };
205
206 void Texture::GetDefaultTextureCoordinates(UvRect& uv) const
207 {
208   if ((mWidth == mImageWidth) && (mHeight == mImageHeight))
209   {
210     // set the uv's to display 0,0 to 1,1
211     uv.Reset();
212     return;
213   }
214
215   // the texture co-ordinates go from 0 to 1. But the image is smaller than the
216   // texture, so we need to adjust the uv values.
217   float uScale = float(mImageWidth)  / float(mWidth);
218   float vScale = float(mImageHeight) / float(mHeight);
219
220   // bottom left
221   uv.u0 = 0.0f;
222   uv.v0 = 0.0f;
223
224   // top right
225   uv.u2 = uScale;
226   uv.v2 = vScale;
227
228 }
229
230 } // namespace Internal
231
232 } // namespace Dali