Remove forceProcess and forceUpdate flag
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / texture-impl.cpp
1 /*
2  * Copyright (c) 2023 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 <dali/internal/event/rendering/texture-impl.h> // Dali::Internal::Texture
20
21 // INTERNAL INCLUDES
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>
25
26 namespace Dali
27 {
28 namespace Internal
29 {
30 TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, uint32_t width, uint32_t height)
31 {
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();
36   return texture;
37 }
38
39 TexturePtr Texture::New(NativeImageInterface& nativeImageInterface)
40 {
41   TexturePtr texture(new Texture(&nativeImageInterface));
42   texture->Initialize();
43   return texture;
44 }
45
46 Render::TextureKey Texture::GetRenderTextureKey() const
47 {
48   return mTextureKey;
49 }
50
51 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
52 : mEventThreadServices(EventThreadServices::Get()),
53   mTextureKey{},
54   mNativeImage(),
55   mSize(size),
56   mType(type),
57   mFormat(format)
58 {
59 }
60
61 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
62 : mEventThreadServices(EventThreadServices::Get()),
63   mTextureKey{},
64   mNativeImage(nativeImageInterface),
65   mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
66   mType(TextureType::TEXTURE_2D),
67   mFormat(Pixel::RGB888)
68 {
69 }
70
71 void Texture::Initialize()
72 {
73   if(EventThreadServices::IsCoreRunning())
74   {
75     if(mNativeImage)
76     {
77       mTextureKey = Render::Texture::NewKey(mNativeImage);
78     }
79     else
80     {
81       mTextureKey = Render::Texture::NewKey(mType, mFormat, mSize);
82     }
83
84     AddTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
85   }
86 }
87
88 Texture::~Texture()
89 {
90   if(EventThreadServices::IsCoreRunning() && mTextureKey)
91   {
92     RemoveTextureMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
93   }
94 }
95
96 bool Texture::Upload(PixelDataPtr pixelData)
97 {
98   return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
99 }
100
101 bool Texture::Upload(PixelDataPtr pixelData,
102                      uint32_t     layer,
103                      uint32_t     mipmap,
104                      uint32_t     xOffset,
105                      uint32_t     yOffset,
106                      uint32_t     width,
107                      uint32_t     height)
108 {
109   return UploadSubPixelData(pixelData, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight(), layer, mipmap, xOffset, yOffset, width, height);
110 }
111
112 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
113                                  uint32_t     dataXOffset,
114                                  uint32_t     dataYOffset,
115                                  uint32_t     dataWidth,
116                                  uint32_t     dataHeight)
117 {
118   return UploadSubPixelData(pixelData, dataXOffset, dataYOffset, dataWidth, dataHeight, 0u, 0u, 0u, 0u, dataWidth, dataHeight);
119 }
120
121 bool Texture::UploadSubPixelData(PixelDataPtr pixelData,
122                                  uint32_t     dataXOffset,
123                                  uint32_t     dataYOffset,
124                                  uint32_t     dataWidth,
125                                  uint32_t     dataHeight,
126                                  uint32_t     layer,
127                                  uint32_t     mipmap,
128                                  uint32_t     xOffset,
129                                  uint32_t     yOffset,
130                                  uint32_t     width,
131                                  uint32_t     height)
132 {
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 &&
138                      width < max_value &&
139                      height < max_value &&
140                      dataWidth < max_value &&
141                      dataHeight < max_value &&
142                      "Parameter value out of range");
143
144   bool result(false);
145   if(EventThreadServices::IsCoreRunning() && mTextureKey)
146   {
147     if(mNativeImage)
148     {
149       DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
150     }
151     else
152     {
153       uint32_t pixelDataSize = dataWidth * dataHeight;
154       if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
155       {
156         DALI_LOG_ERROR("PixelData is empty\n");
157       }
158       else
159       {
160         Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
161         if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
162         {
163           if(pixelDataSize < width * height)
164           {
165             DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
166           }
167           else if(Pixel::IsCompressed(mFormat) &&
168                   ((dataXOffset != 0) ||
169                    (dataYOffset != 0) ||
170                    (dataWidth != pixelData->GetWidth()) ||
171                    (dataHeight != pixelData->GetHeight())))
172           {
173             DALI_LOG_ERROR("Compressed pixel format don't support SubPixelData upload\n");
174           }
175           else if((dataXOffset + dataWidth > pixelData->GetWidth()) ||
176                   (dataYOffset + dataHeight > pixelData->GetHeight()))
177           {
178             DALI_LOG_ERROR("PixelData of an incorrect subsize when trying to update texture\n");
179           }
180           else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
181                   (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
182           {
183             DALI_LOG_ERROR("Texture update area out of bounds\n");
184           }
185           else
186           {
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);
199
200             result = true;
201           }
202         }
203         else
204         {
205           DALI_LOG_ERROR("Bad format\n");
206         }
207       }
208     }
209   }
210
211   return result;
212 }
213
214 void Texture::GenerateMipmaps()
215 {
216   if(EventThreadServices::IsCoreRunning() && mTextureKey)
217   {
218     GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), mTextureKey);
219   }
220 }
221
222 uint32_t Texture::GetWidth() const
223 {
224   return mSize.GetWidth();
225 }
226
227 uint32_t Texture::GetHeight() const
228 {
229   return mSize.GetHeight();
230 }
231
232 Pixel::Format Texture::GetPixelFormat() const
233 {
234   return mFormat;
235 }
236
237 bool Texture::IsNative() const
238 {
239   return static_cast<bool>(mNativeImage);
240 }
241
242 bool Texture::ApplyNativeFragmentShader(std::string& shader)
243 {
244   bool modified = false;
245   if(mNativeImage && !shader.empty())
246   {
247     modified = mNativeImage->ApplyNativeFragmentShader(shader);
248   }
249
250   return modified;
251 }
252
253 } // namespace Internal
254 } // namespace Dali