2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "gles-graphics-texture.h"
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/gl-abstraction.h>
24 #include <dali/integration-api/gl-defines.h>
28 #include "egl-graphics-controller.h"
29 #include "gles-graphics-sampler.h"
30 #include "gles-graphics-types.h"
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;
39 // These are the Dali defaults
40 const int32_t DALI_MINIFY_DEFAULT = GL_LINEAR;
41 const int32_t DALI_MAGNIFY_DEFAULT = GL_LINEAR;
44 namespace Dali::Graphics::GLES
46 Texture::Texture(const Graphics::TextureCreateInfo& createInfo, Graphics::EglGraphicsController& controller)
47 : TextureResource(createInfo, controller)
49 // If there is any data, move it into staging buffer
50 if(mCreateInfo.data && mCreateInfo.dataSize)
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());
58 // Add texture to the Resource queue
59 mController.AddTexture(*this);
62 bool Texture::InitializeResource()
64 if(mCreateInfo.nativeImagePtr)
66 return InitializeNativeImage();
68 return InitializeTexture();
71 bool Texture::InitializeNativeImage()
73 auto gl = mController.GetGL();
76 NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
77 bool created = nativeImage->CreateResource();
78 mGlTarget = nativeImage->GetTextureTarget();
81 DALI_LOG_RELEASE_INFO("Native Image: InitializeNativeImage, CreateResource() successful\n");
83 gl->GenTextures(1, &texture);
84 gl->BindTexture(mGlTarget, texture);
86 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
88 // Apply default sampling parameters
89 gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
90 gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
91 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
92 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
94 // platform specific implementation decides on what GL extension to use
95 if(nativeImage->TargetTexture() != 0u)
97 gl->DeleteTextures(1, &texture);
98 nativeImage->DestroyResource();
104 mTextureId = texture;
109 DALI_LOG_ERROR("Native Image: InitializeNativeImage, CreateResource() failed\n");
112 return created; // WARNING! May be false! Needs handling! (Well, initialized on bind)
115 bool Texture::InitializeTexture()
117 auto gl = mController.GetGL();
121 mGlTarget = GLTextureTarget(mCreateInfo.textureType).target;
123 switch(mCreateInfo.textureType)
126 case Graphics::TextureType::TEXTURE_2D:
128 Graphics::GLES::GLTextureFormatType format(mCreateInfo.format);
130 // TODO: find better condition, with this test the L8 doesn't work
131 if(1) //format.format && format.type)
134 gl->GenTextures(1, &texture);
135 gl->BindTexture(GL_TEXTURE_2D, texture);
137 // Allocate memory for the texture
138 gl->TexImage2D(GL_TEXTURE_2D,
141 mCreateInfo.size.width,
142 mCreateInfo.size.height,
146 (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
148 // Clear staging buffer if there was any
149 mStagingBuffer.clear();
151 mTextureId = texture;
153 // Default texture filtering (to be set later via command buffer binding)
154 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Graphics::GLES::GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter::LINEAR, SamplerMipmapMode::NONE));
155 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Graphics::GLES::GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter::LINEAR, SamplerMipmapMode::NONE));
167 void Texture::DestroyResource()
169 // This is a proper destructor
172 auto gl = mController.GetGL();
173 gl->DeleteTextures(1, &mTextureId);
175 if(mCreateInfo.nativeImagePtr)
177 mCreateInfo.nativeImagePtr->DestroyResource();
181 void Texture::DiscardResource()
183 mController.DiscardResource(this);
186 void Texture::Bind(const TextureBinding& binding) const
188 auto gl = mController.GetGL();
190 gl->ActiveTexture(GL_TEXTURE0 + binding.binding);
191 gl->BindTexture(mGlTarget, mTextureId);
193 // For GLES2 if there is a sampler set in the binding
197 auto* sampler = static_cast<const GLES::Sampler*>(binding.sampler);
198 const auto& samplerCreateInfo = sampler->GetCreateInfo();
200 auto mipMapMode = samplerCreateInfo.mipMapMode;
201 mipMapMode = Graphics::SamplerMipmapMode::NONE; // @todo Remove when mip-map generation is supported
203 gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, GLSamplerFilterAndMipMapMode(samplerCreateInfo.minFilter, mipMapMode).glFilter);
204 gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, GLSamplerFilter(samplerCreateInfo.magFilter).glFilter);
205 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GLAddressMode(samplerCreateInfo.addressModeU).texParameter);
206 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GLAddressMode(samplerCreateInfo.addressModeV).texParameter);
207 if(mGlTarget == GL_TEXTURE_CUBE_MAP)
209 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GLAddressMode(samplerCreateInfo.addressModeW).texParameter);
214 gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
215 gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
216 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
217 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
218 if(mGlTarget == GL_TEXTURE_CUBE_MAP)
220 gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT);
225 void Texture::Prepare()
227 NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
230 DALI_LOG_RELEASE_INFO("Native Image: PrepareTexture\n");
231 if(nativeImage->SourceChanged())
234 uint32_t width = mCreateInfo.nativeImagePtr->GetWidth();
235 uint32_t height = mCreateInfo.nativeImagePtr->GetHeight();
236 mCreateInfo.SetSize({width, height}); // Size may change
239 nativeImage->PrepareTexture();
243 } // namespace Dali::Graphics::GLES