2 * Copyright (c) 2023 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>
30 TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, uint32_t width, uint32_t height)
32 constexpr auto max_value = std::numeric_limits<uint16_t>::max();
33 DALI_ASSERT_ALWAYS((width < max_value) && (height < max_value) && "Size out of range");
34 TexturePtr texture(new Texture(type, format, ImageDimensions(width, height)));
35 texture->Initialize();
39 TexturePtr Texture::New(NativeImageInterface& nativeImageInterface)
41 TexturePtr texture(new Texture(&nativeImageInterface));
42 texture->Initialize();
46 TexturePtr Texture::New(TextureType::Type type, uint32_t resourceId)
48 TexturePtr texture(new Texture(type, resourceId));
49 texture->Initialize();
53 Render::TextureKey Texture::GetRenderTextureKey() const
58 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
59 : mEventThreadServices(EventThreadServices::Get()),
66 mUseUploadedParameter(mSize.GetWidth() == 0u && mSize.GetHeight() == 0u && mFormat == Pixel::INVALID)
70 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
71 : mEventThreadServices(EventThreadServices::Get()),
73 mNativeImage(nativeImageInterface),
74 mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
75 mType(TextureType::TEXTURE_2D),
76 mFormat(Pixel::RGB888),
78 mUseUploadedParameter(false)
82 Texture::Texture(TextureType::Type type, uint32_t resourceId)
83 : mEventThreadServices(EventThreadServices::Get()),
88 mFormat(Pixel::INVALID),
89 mResourceId(resourceId),
90 mUseUploadedParameter(true)
94 void Texture::Initialize()
96 if(EventThreadServices::IsCoreRunning())
100 mTextureKey = Render::Texture::NewKey(mNativeImage);
104 if(mResourceId != 0u)
106 mTextureKey = Render::Texture::NewKey(mType, mResourceId);
110 mTextureKey = Render::Texture::NewKey(mType, mFormat, mSize);
114 AddTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
120 if(EventThreadServices::IsCoreRunning() && mTextureKey)
122 RemoveTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
126 bool Texture::Upload(PixelDataPtr pixelData)
128 return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
131 bool Texture::Upload(PixelDataPtr pixelData,
139 return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), layer, mipmap, xOffset, yOffset, width, height);
142 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
143 uint32_t dataXOffset,
144 uint32_t dataYOffset,
148 return UploadSubPixelData(pixelData, dataXOffset, dataYOffset, dataWidth, dataHeight, 0u, 0u, 0u, 0u, dataWidth, dataHeight);
151 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
152 uint32_t dataXOffset,
153 uint32_t dataYOffset,
163 constexpr auto max_value = std::numeric_limits<uint16_t>::max();
164 DALI_ASSERT_ALWAYS(layer < max_value &&
165 mipmap < max_value &&
166 xOffset + width < max_value &&
167 yOffset + height < max_value &&
168 dataWidth < max_value &&
169 dataHeight < max_value &&
170 "Parameter value out of range");
173 if(EventThreadServices::IsCoreRunning() && mTextureKey)
177 DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
179 else if(mResourceId != 0u)
181 DALI_LOG_ERROR("ResourceId using case does not support uploading data\n");
185 uint32_t pixelDataSize = dataWidth * dataHeight;
186 if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
188 DALI_LOG_ERROR("PixelData is empty\n");
192 Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
193 if((mUseUploadedParameter || pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
195 if(pixelDataSize < width * height)
197 DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
199 else if(Pixel::IsCompressed(mFormat) &&
200 ((dataXOffset != 0) ||
201 (dataYOffset != 0) ||
202 (dataWidth != pixelData->GetWidth()) ||
203 (dataHeight != pixelData->GetHeight())))
205 DALI_LOG_ERROR("Compressed pixel format don't support SubPixelData upload\n");
207 else if((dataXOffset + dataWidth > pixelData->GetWidth()) ||
208 (dataYOffset + dataHeight > pixelData->GetHeight()))
210 DALI_LOG_ERROR("PixelData of an incorrect subsize when trying to update texture\n");
212 else if(!mUseUploadedParameter &&
213 ((xOffset + width > (static_cast<uint32_t>(mSize.GetWidth()) >> mipmap)) ||
214 (yOffset + height > (static_cast<uint32_t>(mSize.GetHeight()) >> mipmap))))
216 DALI_LOG_ERROR("Texture update area out of bounds\n");
220 if(mUseUploadedParameter)
222 mSize = ImageDimensions(xOffset + width, yOffset + height);
223 mFormat = pixelDataFormat;
226 //Parameters are correct. Send message to upload data to the texture
227 Graphics::UploadParams params = {static_cast<uint32_t>(dataXOffset),
228 static_cast<uint32_t>(dataYOffset),
229 static_cast<uint16_t>(dataWidth),
230 static_cast<uint16_t>(dataHeight),
231 static_cast<uint16_t>(layer),
232 static_cast<uint16_t>(mipmap),
233 static_cast<uint16_t>(xOffset),
234 static_cast<uint16_t>(yOffset),
235 static_cast<uint16_t>(width),
236 static_cast<uint16_t>(height)};
237 UploadTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey, pixelData, params);
244 DALI_LOG_ERROR("Bad format\n");
253 void Texture::GenerateMipmaps()
255 if(EventThreadServices::IsCoreRunning() && mTextureKey)
257 GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
261 uint32_t Texture::GetWidth() const
263 return mSize.GetWidth();
266 uint32_t Texture::GetHeight() const
268 return mSize.GetHeight();
271 Pixel::Format Texture::GetPixelFormat() const
276 uint32_t Texture::GetResourceId() const
281 Dali::TextureType::Type Texture::GetTextureType() const
286 void Texture::SetSize(const ImageDimensions& size)
289 if(EventThreadServices::IsCoreRunning() && mTextureKey)
291 SetTextureSizeMessage(mEventThreadServices.GetUpdateManager(), mTextureKey, mSize);
295 void Texture::SetPixelFormat(Pixel::Format format)
298 if(EventThreadServices::IsCoreRunning() && mTextureKey)
300 SetTextureFormatMessage(mEventThreadServices.GetUpdateManager(), mTextureKey, mFormat);
304 bool Texture::IsNative() const
306 return static_cast<bool>(mNativeImage);
309 bool Texture::ApplyNativeFragmentShader(std::string& shader)
311 bool modified = false;
312 if(mNativeImage && !shader.empty())
314 modified = mNativeImage->ApplyNativeFragmentShader(shader);
320 } // namespace Internal