3ddf52bbb61887d8ffeeb50dd62d2f36afde1390
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / texture-impl.cpp
1 /*
2  * Copyright (c) 2021 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, unsigned int width, unsigned int 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
44   // Request event processing and update forcely.
45   texture->mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
46   texture->mEventThreadServices.ForceNextUpdate();
47   return texture;
48 }
49
50 Render::Texture* Texture::GetRenderObject() const
51 {
52   return mRenderObject;
53 }
54
55 Texture::Texture(TextureType::Type type, Pixel::Format format, ImageDimensions size)
56 : mEventThreadServices(EventThreadServices::Get()),
57   mRenderObject(nullptr),
58   mNativeImage(),
59   mSize(size),
60   mType(type),
61   mFormat(format)
62 {
63 }
64
65 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
66 : mEventThreadServices(EventThreadServices::Get()),
67   mRenderObject(nullptr),
68   mNativeImage(nativeImageInterface),
69   mSize(nativeImageInterface->GetWidth(), nativeImageInterface->GetHeight()),
70   mType(TextureType::TEXTURE_2D),
71   mFormat(Pixel::RGB888)
72 {
73 }
74
75 void Texture::Initialize()
76 {
77   if(EventThreadServices::IsCoreRunning())
78   {
79     if(mNativeImage)
80     {
81       mRenderObject = new Render::Texture(mNativeImage);
82     }
83     else
84     {
85       mRenderObject = new Render::Texture(mType, mFormat, mSize);
86     }
87
88     OwnerPointer<Render::Texture> transferOwnership(mRenderObject);
89     AddTexture(mEventThreadServices.GetUpdateManager(), transferOwnership);
90   }
91 }
92
93 Texture::~Texture()
94 {
95   if(EventThreadServices::IsCoreRunning() && mRenderObject)
96   {
97     RemoveTexture(mEventThreadServices.GetUpdateManager(), *mRenderObject);
98   }
99 }
100
101 bool Texture::Upload(PixelDataPtr pixelData)
102 {
103   return Upload(pixelData, 0u, 0u, 0u, 0u, pixelData->GetWidth(), pixelData->GetHeight());
104 }
105
106 bool Texture::Upload(PixelDataPtr pixelData,
107                      unsigned int layer,
108                      unsigned int mipmap,
109                      unsigned int xOffset,
110                      unsigned int yOffset,
111                      unsigned int width,
112                      unsigned int height)
113 {
114   constexpr auto max_value = std::numeric_limits<uint16_t>::max();
115   DALI_ASSERT_ALWAYS(layer < max_value &&
116                      mipmap < max_value &&
117                      xOffset < max_value &&
118                      yOffset < max_value &&
119                      width < max_value &&
120                      height < max_value &&
121                      "Parameter value out of range");
122
123   bool result(false);
124   if(EventThreadServices::IsCoreRunning() && mRenderObject)
125   {
126     if(mNativeImage)
127     {
128       DALI_LOG_ERROR("OpenGL ES does not support uploading data to native texture\n");
129     }
130     else
131     {
132       unsigned int pixelDataSize = pixelData->GetWidth() * pixelData->GetHeight();
133       if(pixelData->GetBuffer() == nullptr || pixelDataSize == 0)
134       {
135         DALI_LOG_ERROR("PixelData is empty\n");
136       }
137       else
138       {
139         Pixel::Format pixelDataFormat = pixelData->GetPixelFormat();
140         if((pixelDataFormat == mFormat) || ((pixelDataFormat == Pixel::RGB888) && (mFormat == Pixel::RGBA8888)))
141         {
142           if(pixelDataSize < width * height)
143           {
144             DALI_LOG_ERROR("PixelData of an incorrect size when trying to update texture\n");
145           }
146           else if((xOffset + width > (mSize.GetWidth() / (1u << mipmap))) ||
147                   (yOffset + height > (mSize.GetHeight() / (1u << mipmap))))
148           {
149             DALI_LOG_ERROR("Texture update area out of bounds\n");
150           }
151           else
152           {
153             //Parameters are correct. Send message to upload data to the texture
154             UploadParams params = {static_cast<uint16_t>(layer),
155                                    static_cast<uint16_t>(mipmap),
156                                    static_cast<uint16_t>(xOffset),
157                                    static_cast<uint16_t>(yOffset),
158                                    static_cast<uint16_t>(width),
159                                    static_cast<uint16_t>(height)};
160             UploadTextureMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params);
161
162             // Request event processing and update forcely
163             mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle(true);
164             mEventThreadServices.ForceNextUpdate();
165
166             result = true;
167           }
168         }
169         else
170         {
171           DALI_LOG_ERROR("Bad format\n");
172         }
173       }
174     }
175   }
176
177   return result;
178 }
179
180 void Texture::GenerateMipmaps()
181 {
182   if(EventThreadServices::IsCoreRunning() && mRenderObject)
183   {
184     GenerateMipmapsMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject);
185   }
186 }
187
188 unsigned int Texture::GetWidth() const
189 {
190   return mSize.GetWidth();
191 }
192
193 unsigned int Texture::GetHeight() const
194 {
195   return mSize.GetHeight();
196 }
197
198 bool Texture::IsNative() const
199 {
200   return mNativeImage != nullptr;
201 }
202
203 bool Texture::ApplyNativeFragmentShader(std::string& shader)
204 {
205   bool modified = false;
206   if(mNativeImage != nullptr && !shader.empty())
207   {
208     modified = mNativeImage->ApplyNativeFragmentShader(shader);
209   }
210
211   return modified;
212 }
213
214 } // namespace Internal
215 } // namespace Dali