Add API for setting resource destruction callback
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / windows / native-image-source-impl-win.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/imaging/windows/native-image-source-impl-win.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/adaptor-framework/render-surface-interface.h>
26 #include <dali/internal/adaptor/common/adaptor-impl.h>
27 #include <dali/internal/graphics/common/egl-image-extensions.h>
28 #include <dali/internal/graphics/gles/egl-graphics.h>
29 #include <dali/internal/window-system/windows/platform-implement-win.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35 namespace Adaptor
36 {
37 using Dali::Integration::PixelBuffer;
38
39 NativeImageSourceWin* NativeImageSourceWin::New(unsigned int width, unsigned int height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource)
40 {
41   NativeImageSourceWin* image = new NativeImageSourceWin(width, height, depth, nativeImageSource);
42   DALI_ASSERT_DEBUG(image && "NativeImageSource allocation failed.");
43
44   // 2nd phase construction
45   if(image) //< Defensive in case we ever compile without exceptions.
46   {
47     image->Initialize();
48   }
49
50   return image;
51 }
52
53 NativeImageSourceWin::NativeImageSourceWin(unsigned int width, unsigned int height, Dali::NativeImageSource::ColorDepth depth, Any nativeImageSource)
54 : mWidth(width),
55   mHeight(height),
56   mOwnPixmap(true),
57   mPixmap(0),
58   mBlendingRequired(false),
59   mColorDepth(depth),
60   mEglImageKHR(NULL),
61   mEglImageExtensions(NULL),
62   mResourceDestructionCallback()
63 {
64   DALI_ASSERT_ALWAYS(Adaptor::IsAvailable());
65
66   GraphicsInterface* graphics    = &(Adaptor::GetImplementation(Adaptor::Get()).GetGraphicsInterface());
67   auto               eglGraphics = static_cast<EglGraphics*>(graphics);
68
69   mEglImageExtensions = eglGraphics->GetImageExtensions();
70
71   DALI_ASSERT_DEBUG(mEglImageExtensions);
72
73   // assign the pixmap
74   mPixmap = GetPixmapFromAny(nativeImageSource);
75 }
76
77 void NativeImageSourceWin::Initialize()
78 {
79   // if pixmap has been created outside of Windows Image we can return
80   if(mPixmap)
81   {
82     // we don't own the pixmap
83     mOwnPixmap = false;
84
85     // find out the pixmap width / height and color depth
86     GetPixmapDetails();
87     return;
88   }
89
90   // get the pixel depth
91   int depth = GetPixelDepth(mColorDepth);
92
93   // set whether blending is required according to pixel format based on the depth
94   /* default pixel format is RGB888
95      If depth = 8, Pixel::A8;
96      If depth = 16, Pixel::RGB565;
97      If depth = 32, Pixel::RGBA8888 */
98   mBlendingRequired = (depth == 32 || depth == 8);
99 }
100
101 NativeImageSourceWin::~NativeImageSourceWin()
102 {
103 }
104
105 Any NativeImageSourceWin::GetNativeImageSource() const
106 {
107   return Any(mPixmap);
108 }
109
110 bool NativeImageSourceWin::GetPixels(std::vector<uint8_t>& pixbuf, unsigned& width, unsigned& height, Pixel::Format& pixelFormat) const
111 {
112   DALI_ASSERT_DEBUG(sizeof(unsigned) == 4);
113   bool success = false;
114   width        = mWidth;
115   height       = mHeight;
116
117   return success;
118 }
119
120 void NativeImageSourceWin::SetSource(Any source)
121 {
122   mPixmap = GetPixmapFromAny(source);
123
124   if(mPixmap)
125   {
126     // we don't own the pixmap
127     mOwnPixmap = false;
128
129     // find out the pixmap width / height and color depth
130     GetPixmapDetails();
131   }
132 }
133
134 bool NativeImageSourceWin::IsColorDepthSupported(Dali::NativeImageSource::ColorDepth colorDepth)
135 {
136   return true;
137 }
138
139 bool NativeImageSourceWin::CreateResource()
140 {
141   // if the image existed previously delete it.
142   if(mEglImageKHR != NULL)
143   {
144     DestroyResource();
145   }
146
147   // casting from an unsigned int to a void *, which should then be cast back
148   // to an unsigned int in the driver.
149   EGLClientBuffer eglBuffer = reinterpret_cast<EGLClientBuffer>(mPixmap);
150
151   mEglImageKHR = mEglImageExtensions->CreateImageKHR(eglBuffer);
152
153   return mEglImageKHR != NULL;
154 }
155
156 void NativeImageSourceWin::DestroyResource()
157 {
158   mEglImageExtensions->DestroyImageKHR(mEglImageKHR);
159
160   mEglImageKHR = NULL;
161
162   if(mResourceDestructionCallback)
163   {
164     mResourceDestructionCallback->Trigger();
165   }
166 }
167
168 unsigned int NativeImageSourceWin::TargetTexture()
169 {
170   mEglImageExtensions->TargetTextureKHR(mEglImageKHR);
171
172   return 0;
173 }
174
175 void NativeImageSourceWin::PrepareTexture()
176 {
177 }
178
179 int NativeImageSourceWin::GetPixelDepth(Dali::NativeImageSource::ColorDepth depth) const
180 {
181   switch(depth)
182   {
183     case Dali::NativeImageSource::COLOR_DEPTH_DEFAULT:
184     {
185       return 32;
186     }
187     case Dali::NativeImageSource::COLOR_DEPTH_8:
188     {
189       return 8;
190     }
191     case Dali::NativeImageSource::COLOR_DEPTH_16:
192     {
193       return 16;
194     }
195     case Dali::NativeImageSource::COLOR_DEPTH_24:
196     {
197       return 24;
198     }
199     case Dali::NativeImageSource::COLOR_DEPTH_32:
200     {
201       return 32;
202     }
203     default:
204     {
205       DALI_ASSERT_DEBUG(0 && "unknown color enum");
206       return 0;
207     }
208   }
209 }
210
211 unsigned int NativeImageSourceWin::GetPixmapFromAny(Any pixmap) const
212 {
213   if(pixmap.Empty())
214   {
215     return 0;
216   }
217
218   // see if it is of type Windows pixmap
219   if(pixmap.GetType() == typeid(unsigned int))
220   {
221     // get the Windows pixmap type
222     unsigned int xpixmap = AnyCast<unsigned int>(pixmap);
223
224     // cast it to a Windows pixmap type
225     return static_cast<unsigned int>(xpixmap);
226   }
227   else
228   {
229     return AnyCast<unsigned int>(pixmap);
230   }
231 }
232
233 void NativeImageSourceWin::GetPixmapDetails()
234 {
235 }
236
237 bool NativeImageSourceWin::ApplyNativeFragmentShader(std::string& shader)
238 {
239   return false;
240 }
241
242 const char* NativeImageSourceWin::GetCustomSamplerTypename() const
243 {
244   return nullptr;
245 }
246
247 int NativeImageSourceWin::GetTextureTarget() const
248 {
249   return GL_TEXTURE_2D;
250 }
251
252 Any NativeImageSourceWin::GetNativeImageHandle() const
253 {
254   return mPixmap;
255 }
256
257 bool NativeImageSourceWin::SourceChanged() const
258 {
259   return false;
260 }
261
262 uint8_t* NativeImageSourceWin::AcquireBuffer(uint16_t& width, uint16_t& height, uint16_t& stride)
263 {
264   return NULL;
265 }
266
267 bool NativeImageSourceWin::ReleaseBuffer()
268 {
269   return false;
270 }
271
272 void NativeImageSourceWin::SetResourceDestructionCallback(EventThreadCallback* callback)
273 {
274   mResourceDestructionCallback = std::unique_ptr<EventThreadCallback>(callback);
275 }
276
277 } // namespace Adaptor
278
279 } // namespace Internal
280
281 } // namespace Dali