Merge "Fixed reported SVACE error in hyphenation-impl.cpp" into devel/master
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / gles-graphics-texture.cpp
1 /*
2  * Copyright (c) 2021 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 "gles-graphics-texture.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-abstraction.h>
24 #include <dali/integration-api/gl-defines.h>
25 #include <vector>
26
27 // INTERNAL INCLUDES
28 #include "egl-graphics-controller.h"
29 #include "gles-graphics-sampler.h"
30 #include "gles-graphics-types.h"
31
32 namespace
33 {
34 // These match the GL specification
35 //const int32_t GL_MINIFY_DEFAULT  = GL_NEAREST_MIPMAP_LINEAR;
36 //const int32_t GL_MAGNIFY_DEFAULT = GL_LINEAR;
37 const int32_t GL_WRAP_DEFAULT = GL_CLAMP_TO_EDGE;
38
39 // These are the Dali defaults
40 const int32_t DALI_MINIFY_DEFAULT  = GL_LINEAR;
41 const int32_t DALI_MAGNIFY_DEFAULT = GL_LINEAR;
42 } // namespace
43
44 namespace Dali::Graphics::GLES
45 {
46 Texture::Texture(const Graphics::TextureCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
47 : TextureResource(createInfo, controller)
48 {
49   // If there is any data, move it into staging buffer
50   if(mCreateInfo.data && mCreateInfo.dataSize)
51   {
52     mStagingBuffer.resize(size_t(mCreateInfo.dataSize));
53     std::copy(reinterpret_cast<char*>(mCreateInfo.data),
54               reinterpret_cast<char*>(mCreateInfo.data) + mCreateInfo.dataSize,
55               mStagingBuffer.begin());
56   }
57
58   // Add texture to the Resource queue
59   mController.AddTexture(*this);
60 }
61
62 bool Texture::InitializeResource()
63 {
64   if(mCreateInfo.nativeImagePtr)
65   {
66     return InitializeNativeImage();
67   }
68   return InitializeTexture();
69 }
70
71 bool Texture::InitializeNativeImage()
72 {
73   auto   gl = mController.GetGL();
74   GLuint texture{0};
75
76   if(!gl)
77   {
78     // Do nothing during shutdown
79     return false;
80   }
81
82   NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
83   bool                    created     = nativeImage->CreateResource();
84   mGlTarget                           = nativeImage->GetTextureTarget();
85   if(created)
86   {
87     gl->GenTextures(1, &texture);
88     gl->BindTexture(mGlTarget, texture);
89
90     gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
91
92     // Apply default sampling parameters
93     gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
94     gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
95     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
96     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
97
98     // platform specific implementation decides on what GL extension to use
99     if(nativeImage->TargetTexture() != 0u)
100     {
101       gl->DeleteTextures(1, &texture);
102       nativeImage->DestroyResource();
103       texture = 0u;
104       created = false;
105     }
106     else
107     {
108       mTextureId = texture;
109     }
110   }
111   else
112   {
113     DALI_LOG_ERROR("Native Image: InitializeNativeImage, CreateResource() failed\n");
114   }
115
116   return created; // WARNING! May be false! Needs handling! (Well, initialized on bind)
117 }
118
119 bool Texture::InitializeTexture()
120 {
121   auto gl = mController.GetGL();
122   if(!gl)
123   {
124     // Do nothing during shutdown
125     return false;
126   }
127
128   GLuint texture{0};
129
130   mGlTarget = GLTextureTarget(mCreateInfo.textureType).target;
131
132   switch(mCreateInfo.textureType)
133   {
134     // Texture 2D
135     case Graphics::TextureType::TEXTURE_2D:
136     {
137       Graphics::GLES::GLTextureFormatType format(mCreateInfo.format);
138
139       // TODO: find better condition, with this test the L8 doesn't work
140       if(1) //format.format && format.type)
141       {
142         // Bind texture
143         gl->GenTextures(1, &texture);
144         gl->BindTexture(GL_TEXTURE_2D, texture);
145
146         // Allocate memory for the texture
147         gl->TexImage2D(GL_TEXTURE_2D,
148                        0,
149                        format.format,
150                        mCreateInfo.size.width,
151                        mCreateInfo.size.height,
152                        0,
153                        format.format,
154                        format.type,
155                        (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
156
157         // Clear staging buffer if there was any
158         mStagingBuffer.clear();
159
160         mTextureId = texture;
161
162         // Default texture filtering (to be set later via command buffer binding)
163         gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Graphics::GLES::GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter::LINEAR, SamplerMipmapMode::NONE));
164         gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Graphics::GLES::GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter::LINEAR, SamplerMipmapMode::NONE));
165       }
166       break;
167     }
168     default:
169     {
170       // nothing?
171     }
172   }
173   return true;
174 }
175
176 void Texture::DestroyResource()
177 {
178   auto gl = mController.GetGL();
179   if(!gl)
180   {
181     return;
182   }
183
184   // This is a proper destructor
185   if(mTextureId)
186   {
187     gl->DeleteTextures(1, &mTextureId);
188   }
189   if(mCreateInfo.nativeImagePtr)
190   {
191     mCreateInfo.nativeImagePtr->DestroyResource();
192   }
193 }
194
195 void Texture::DiscardResource()
196 {
197   mController.DiscardResource(this);
198 }
199
200 void Texture::Bind(const TextureBinding& binding) const
201 {
202   auto gl = mController.GetGL();
203   if(!gl)
204   {
205     // Do nothing during shutdown
206     return;
207   }
208
209   gl->ActiveTexture(GL_TEXTURE0 + binding.binding);
210   gl->BindTexture(mGlTarget, mTextureId);
211
212   // For GLES2 if there is a sampler set in the binding
213   if(binding.sampler)
214   {
215     // Non-default.
216     auto*       sampler           = static_cast<const GLES::Sampler*>(binding.sampler);
217     const auto& samplerCreateInfo = sampler->GetCreateInfo();
218
219     auto mipMapMode = samplerCreateInfo.mipMapMode;
220     mipMapMode      = Graphics::SamplerMipmapMode::NONE; // @todo Remove when mip-map generation is supported
221
222     gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, GLSamplerFilterAndMipMapMode(samplerCreateInfo.minFilter, mipMapMode).glFilter);
223     gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, GLSamplerFilter(samplerCreateInfo.magFilter).glFilter);
224     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GLAddressMode(samplerCreateInfo.addressModeU).texParameter);
225     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GLAddressMode(samplerCreateInfo.addressModeV).texParameter);
226     if(mGlTarget == GL_TEXTURE_CUBE_MAP)
227     {
228       gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GLAddressMode(samplerCreateInfo.addressModeW).texParameter);
229     }
230   }
231   else
232   {
233     gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
234     gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
235     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
236     gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
237     if(mGlTarget == GL_TEXTURE_CUBE_MAP)
238     {
239       gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT);
240     }
241   }
242 }
243
244 void Texture::Prepare()
245 {
246   NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
247   if(nativeImage)
248   {
249     if(nativeImage->SourceChanged())
250     {
251       // Update size
252       uint32_t width  = mCreateInfo.nativeImagePtr->GetWidth();
253       uint32_t height = mCreateInfo.nativeImagePtr->GetHeight();
254       mCreateInfo.SetSize({width, height}); // Size may change
255     }
256
257     nativeImage->PrepareTexture();
258   }
259 }
260
261 } // namespace Dali::Graphics::GLES