2 * Copyright (c) 2020 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 <dali/internal/event/rendering/texture-impl.h> // Dali::Internal::Texture
22 #include <dali/integration-api/render-controller.h>
23 #include <dali/internal/event/common/stage-impl.h>
24 #include <dali/internal/update/manager/update-manager.h>
31 const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
38 TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height)
40 constexpr auto max_value = std::numeric_limits<uint16_t>::max();
41 DALI_ASSERT_ALWAYS((width < max_value) && (height < max_value) && "Size out of range");
42 TexturePtr texture(new Texture(type, format, ImageDimensions(width, height)));
43 texture->Initialize();
47 TexturePtr Texture::New(NativeImageInterface& nativeImageInterface)
49 TexturePtr texture(new Texture(&nativeImageInterface));
50 texture->Initialize();
52 // Request event processing and update forcely.
53 texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
54 texture->mEventThreadServices.ForceNextUpdate();
58 Render::Texture* Texture::GetRenderObject() const
63 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
64 : mEventThreadServices(EventThreadServices::Get()),
65 mRenderObject(nullptr),
73 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
74 : mEventThreadServices(EventThreadServices::Get()),
75 mRenderObject(nullptr),
76 mNativeImage(nativeImageInterface),
77 mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
78 mType(TextureType::TEXTURE_2D),
79 mFormat(Pixel::RGB888)
83 void Texture::Initialize()
85 if(EventThreadServices::IsCoreRunning())
89 mRenderObject = new Render::Texture(mNativeImage);
93 mRenderObject = new Render::Texture(mType, mFormat, mSize);
96 OwnerPointer<Render::Texture> transferOwnership(mRenderObject);
97 AddTexture(mEventThreadServices.GetUpdateManager(), transferOwnership);
103 if(EventThreadServices::IsCoreRunning() && mRenderObject)
105 RemoveTexture(mEventThreadServices.GetUpdateManager(), *mRenderObject);
109 bool Texture::Upload(PixelDataPtr pixelData)
111 return Upload(pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
114 bool Texture::Upload(PixelDataPtr pixelData,
117 unsigned int xOffset,
118 unsigned int yOffset,
122 constexpr auto max_value = std::numeric_limits<uint16_t>::max();
123 DALI_ASSERT_ALWAYS(layer < max_value &&
124 mipmap < max_value &&
125 xOffset < max_value &&
126 yOffset < max_value &&
128 height < max_value &&
129 "Parameter value out of range");
132 if(EventThreadServices::IsCoreRunning() && mRenderObject)
136 DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
140 unsigned int pixelDataSize = pixelData->GetWidth() * pixelData->GetHeight();
141 if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
143 DALI_LOG_ERROR("PixelData is empty\n");
147 Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
148 if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
150 if(pixelDataSize < width * height)
152 DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
154 else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
155 (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
157 DALI_LOG_ERROR("Texture update area out of bounds\n");
161 //Parameters are correct. Send message to upload data to the texture
162 UploadParams params = {static_cast<uint16_t>(layer),
163 static_cast<uint16_t>(mipmap),
164 static_cast<uint16_t>(xOffset),
165 static_cast<uint16_t>(yOffset),
166 static_cast<uint16_t>(width),
167 static_cast<uint16_t>(height)};
168 UploadTextureMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params);
170 // Request event processing and update forcely
171 mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
172 mEventThreadServices.ForceNextUpdate();
179 DALI_LOG_ERROR("Bad format\n");
188 void Texture::GenerateMipmaps()
190 if(EventThreadServices::IsCoreRunning() && mRenderObject)
192 GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject);
196 unsigned int Texture::GetWidth() const
198 return mSize.GetWidth();
201 unsigned int Texture::GetHeight() const
203 return mSize.GetHeight();
206 bool Texture::IsNative() const
208 return mNativeImage != nullptr;
211 bool Texture::ApplyNativeFragmentShader(std::string& shader)
213 std::string fragmentShader;
214 bool modified = false;
215 if(mNativeImage != nullptr && !shader.empty())
217 const char* fragmentPrefix = mNativeImage->GetCustomFragmentPrefix();
218 const char* customSamplerTypename = mNativeImage->GetCustomSamplerTypename();
220 size_t prefixIndex = shader.find(Dali::Shader::GetShaderVersionPrefix());
221 if(fragmentPrefix != nullptr)
224 if(prefixIndex == std::string::npos)
226 fragmentShader = fragmentPrefix;
227 fragmentShader += "\n";
231 fragmentShader.clear();
232 shader.insert(prefixIndex + Dali::Shader::GetShaderVersionPrefix().length(), std::string(fragmentPrefix) + "\n");
235 fragmentShader += shader;
237 if(customSamplerTypename != nullptr)
240 size_t pos = fragmentShader.find(DEFAULT_SAMPLER_TYPENAME);
241 if(pos < fragmentShader.length())
243 fragmentShader.replace(pos, strlen(DEFAULT_SAMPLER_TYPENAME), customSamplerTypename);
250 shader = fragmentShader;
256 } // namespace Internal