Clean up the code to build successfully on macOS
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / texture-impl.cpp
1 /*
2  * Copyright (c) 2020 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 // EXTERNAL INCLUDES
27 #include <cstring>
28
29 namespace
30 {
31 const char* DEFAULT_SAMPLER_TYPENAME = "sampler2D";
32 } // namespace
33
34 namespace Dali
35 {
36 namespace Internal
37 {
38 TexturePtr Texture::New(TextureType::Type type, Pixel::Format format, unsigned int width, unsigned int height)
39 {
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();
44   return texture;
45 }
46
47 TexturePtr Texture::New(NativeImageInterface& nativeImageInterface)
48 {
49   TexturePtr texture(new Texture(&nativeImageInterface));
50   texture->Initialize();
51
52   // Request event processing and update forcely.
53   texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
54   texture->mEventThreadServices.ForceNextUpdate();
55   return texture;
56 }
57
58 Render::Texture* Texture::GetRenderObject() const
59 {
60   return mRenderObject;
61 }
62
63 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
64 : mEventThreadServices(EventThreadServices::Get()),
65   mRenderObject(nullptr),
66   mNativeImage(),
67   mSize(size),
68   mType(type),
69   mFormat(format)
70 {
71 }
72
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)
80 {
81 }
82
83 void Texture::Initialize()
84 {
85   if(EventThreadServices::IsCoreRunning())
86   {
87     if(mNativeImage)
88     {
89       mRenderObject = new Render::Texture(mNativeImage);
90     }
91     else
92     {
93       mRenderObject = new Render::Texture(mType, mFormat, mSize);
94     }
95
96     OwnerPointer<Render::Texture> transferOwnership(mRenderObject);
97     AddTexture(mEventThreadServices.GetUpdateManager(), transferOwnership);
98   }
99 }
100
101 Texture::~Texture()
102 {
103   if(EventThreadServices::IsCoreRunning() && mRenderObject)
104   {
105     RemoveTexture(mEventThreadServices.GetUpdateManager(), *mRenderObject);
106   }
107 }
108
109 bool Texture::Upload(PixelDataPtr pixelData)
110 {
111   return Upload(pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
112 }
113
114 bool Texture::Upload(PixelDataPtr pixelData,
115                      unsigned int layer,
116                      unsigned int mipmap,
117                      unsigned int xOffset,
118                      unsigned int yOffset,
119                      unsigned int width,
120                      unsigned int height)
121 {
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 &&
127                      width < max_value &&
128                      height < max_value &&
129                      "Parameter value out of range");
130
131   bool result(false);
132   if(EventThreadServices::IsCoreRunning() && mRenderObject)
133   {
134     if(mNativeImage)
135     {
136       DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
137     }
138     else
139     {
140       unsigned int pixelDataSize = pixelData->GetWidth() * pixelData->GetHeight();
141       if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
142       {
143         DALI_LOG_ERROR("PixelData is empty\n");
144       }
145       else
146       {
147         Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
148         if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
149         {
150           if(pixelDataSize < width * height)
151           {
152             DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
153           }
154           else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
155                   (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
156           {
157             DALI_LOG_ERROR("Texture update area out of bounds\n");
158           }
159           else
160           {
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);
169
170             // Request event processing and update forcely
171             mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
172             mEventThreadServices.ForceNextUpdate();
173
174             result = true;
175           }
176         }
177         else
178         {
179           DALI_LOG_ERROR("Bad format\n");
180         }
181       }
182     }
183   }
184
185   return result;
186 }
187
188 void Texture::GenerateMipmaps()
189 {
190   if(EventThreadServices::IsCoreRunning() && mRenderObject)
191   {
192     GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject);
193   }
194 }
195
196 unsigned int Texture::GetWidth() const
197 {
198   return mSize.GetWidth();
199 }
200
201 unsigned int Texture::GetHeight() const
202 {
203   return mSize.GetHeight();
204 }
205
206 bool Texture::IsNative() const
207 {
208   return mNativeImage != nullptr;
209 }
210
211 bool Texture::ApplyNativeFragmentShader(std::string& shader)
212 {
213   std::string fragmentShader;
214   bool        modified = false;
215   if(mNativeImage != nullptr && !shader.empty())
216   {
217     const char* fragmentPrefix        = mNativeImage->GetCustomFragmentPrefix();
218     const char* customSamplerTypename = mNativeImage->GetCustomSamplerTypename();
219
220     if(fragmentPrefix != nullptr)
221     {
222       modified       = true;
223       fragmentShader = fragmentPrefix;
224       fragmentShader += "\n";
225     }
226     fragmentShader += shader;
227
228     if(customSamplerTypename != nullptr)
229     {
230       modified   = true;
231       size_t pos = fragmentShader.find(DEFAULT_SAMPLER_TYPENAME);
232       if(pos < fragmentShader.length())
233       {
234         fragmentShader.replace(pos, strlen(DEFAULT_SAMPLER_TYPENAME), customSamplerTypename);
235       }
236     }
237   }
238
239   if(modified)
240   {
241     shader = fragmentShader;
242   }
243
244   return modified;
245 }
246
247 } // namespace Internal
248 } // namespace Dali