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 Render::TextureKey Texture::GetRenderTextureKey() const
51 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
52 : mEventThreadServices(EventThreadServices::Get()),
61 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
62 : mEventThreadServices(EventThreadServices::Get()),
64 mNativeImage(nativeImageInterface),
65 mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
66 mType(TextureType::TEXTURE_2D),
67 mFormat(Pixel::RGB888)
71 void Texture::Initialize()
73 if(EventThreadServices::IsCoreRunning())
77 mTextureKey = Render::Texture::NewKey(mNativeImage);
81 mTextureKey = Render::Texture::NewKey(mType, mFormat, mSize);
84 AddTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
90 if(EventThreadServices::IsCoreRunning() && mTextureKey)
92 RemoveTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
96 bool Texture::Upload(PixelDataPtr pixelData)
98 return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
101 bool Texture::Upload(PixelDataPtr pixelData,
109 return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), layer, mipmap, xOffset, yOffset, width, height);
112 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
113 uint32_t dataXOffset,
114 uint32_t dataYOffset,
118 return UploadSubPixelData(pixelData, dataXOffset, dataYOffset, dataWidth, dataHeight, 0u, 0u, 0u, 0u, dataWidth, dataHeight);
121 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
122 uint32_t dataXOffset,
123 uint32_t dataYOffset,
133 constexpr auto max_value = std::numeric_limits<uint16_t>::max();
134 DALI_ASSERT_ALWAYS(layer < max_value &&
135 mipmap < max_value &&
136 xOffset < max_value &&
137 yOffset < max_value &&
139 height < max_value &&
140 dataWidth < max_value &&
141 dataHeight < max_value &&
142 "Parameter value out of range");
145 if(EventThreadServices::IsCoreRunning() && mTextureKey)
149 DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
153 uint32_t pixelDataSize = dataWidth * dataHeight;
154 if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
156 DALI_LOG_ERROR("PixelData is empty\n");
160 Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
161 if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
163 if(pixelDataSize < width * height)
165 DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
167 else if(Pixel::IsCompressed(mFormat) &&
168 ((dataXOffset != 0) ||
169 (dataYOffset != 0) ||
170 (dataWidth != pixelData->GetWidth()) ||
171 (dataHeight != pixelData->GetHeight())))
173 DALI_LOG_ERROR("Compressed pixel format don't support SubPixelData upload\n");
175 else if((dataXOffset + dataWidth > pixelData->GetWidth()) ||
176 (dataYOffset + dataHeight > pixelData->GetHeight()))
178 DALI_LOG_ERROR("PixelData of an incorrect subsize when trying to update texture\n");
180 else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
181 (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
183 DALI_LOG_ERROR("Texture update area out of bounds\n");
187 //Parameters are correct. Send message to upload data to the texture
188 UploadParams params = {static_cast<uint32_t>(dataXOffset),
189 static_cast<uint32_t>(dataYOffset),
190 static_cast<uint16_t>(dataWidth),
191 static_cast<uint16_t>(dataHeight),
192 static_cast<uint16_t>(layer),
193 static_cast<uint16_t>(mipmap),
194 static_cast<uint16_t>(xOffset),
195 static_cast<uint16_t>(yOffset),
196 static_cast<uint16_t>(width),
197 static_cast<uint16_t>(height)};
198 UploadTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey, pixelData, params);
205 DALI_LOG_ERROR("Bad format\n");
214 void Texture::GenerateMipmaps()
216 if(EventThreadServices::IsCoreRunning() && mTextureKey)
218 GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
222 uint32_t Texture::GetWidth() const
224 return mSize.GetWidth();
227 uint32_t Texture::GetHeight() const
229 return mSize.GetHeight();
232 Pixel::Format Texture::GetPixelFormat() const
237 bool Texture::IsNative() const
239 return static_cast<bool>(mNativeImage);
242 bool Texture::ApplyNativeFragmentShader(std::string& shader)
244 bool modified = false;
245 if(mNativeImage && !shader.empty())
247 modified = mNativeImage->ApplyNativeFragmentShader(shader);
253 } // namespace Internal