[NUI] Remove NUI dotnet 6.0 build warnings
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / FrameBroker / FrameBrokerBase.cs
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
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 using System;
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21 using System.Threading.Tasks;
22 using Tizen.Applications;
23 using Tizen.Applications.Exceptions;
24
25 namespace Tizen.NUI
26 {
27     /// <summary>
28     /// Represents the Frame Broker.
29     /// </summary>
30     internal abstract class FrameBrokerBase : IDisposable
31     {
32         private string logTag = "NUI";
33         private readonly SafeFrameBrokerHandle handle;
34         private Dictionary<int, Interop.FrameBroker.AppControlResultCallback> resultCallbackMaps = new Dictionary<int, Interop.FrameBroker.AppControlResultCallback>();
35         private int resultId = 0;
36         private Interop.FrameBroker.FrameContextLifecycleCallbacks callbacks;
37         private IntPtr context = IntPtr.Zero;
38         private bool disposed = false;
39
40         private Renderer renderer;
41         private TextureSet textureSet;
42
43         /// <summary>
44         /// Initializes the FrameBroker class.
45         /// </summary>
46         /// <param name="window">The window instance of Ecore_Wl2_Window pointer.</param>
47         /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
48         /// <exception cref="Applications.Exceptions.OutOfMemoryException">Thrown when the memory is insufficient.</exception>
49         /// <exception cref="InvalidOperationException">Thrown when failed to create the frame broker handle.</exception>
50         /// <remarks>This class is only available for platform level signed applications.</remarks>
51         internal FrameBrokerBase(Window window)
52         {
53             Interop.FrameBroker.ErrorCode err;
54
55             if (window == null)
56             {
57                 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
58             }
59
60             callbacks.OnCreate = new Interop.FrameBroker.FrameContextCreateCallback(OnCreateNative);
61             callbacks.OnResume = new Interop.FrameBroker.FrameContextResumeCallback(OnResumeNavie);
62             callbacks.OnPause = new Interop.FrameBroker.FrameContextPauseCallback(OnPauseNative);
63             callbacks.OnDestroy = new Interop.FrameBroker.FrameContextDestroyCallback(OnDestroyNative);
64             callbacks.OnError = new Interop.FrameBroker.FrameContextErrorCallback(OnErrorNative);
65             callbacks.OnUpdate = new Interop.FrameBroker.FrameContextUpdateCallback(OnUpdateNative);
66
67             err = Interop.FrameBroker.Create(window.GetNativeWindowHandler(), ref callbacks, IntPtr.Zero, out handle);
68             if (err != Interop.FrameBroker.ErrorCode.None)
69             {
70                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to create frame broker handle");
71             }
72         }
73
74         /// <summary>
75         /// Sends the launch request asynchronously.
76         /// </summary>
77         /// <remarks>
78         /// The operation is mandatory information for the launch request.
79         /// If the operation is not specified, AppControlOperations.Default is used by default.
80         /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application.<br/>
81         /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
82         /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
83         /// To launch a service application, an explicit launch request with the application ID given by property ApplicationId MUST be sent.
84         /// </remarks>
85         /// <param name="appControl">The AppControl.</param>
86         /// <returns>A task with the result of the launch request.</returns>
87         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
88         /// <exception cref="AppNotFoundException">Thrown when the application to run is not found.</exception>
89         /// <exception cref="LaunchRejectedException">Thrown when the launch request is rejected.</exception>
90         /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
91         internal Task<FrameBrokerBaseResult> SendLaunchRequest(AppControl appControl)
92         {
93             if (appControl == null)
94             {
95                 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
96             }
97
98             var task = new TaskCompletionSource<FrameBrokerBaseResult>();
99             int requestId = 0;
100
101             lock (resultCallbackMaps)
102             {
103                 requestId = resultId++;
104                 resultCallbackMaps[requestId] = (handle, result, userData) =>
105                 {
106                     task.SetResult((FrameBrokerBaseResult)result);
107                     lock (resultCallbackMaps)
108                     {
109                         resultCallbackMaps.Remove((int)userData);
110                     }
111                 };
112             }
113
114             Interop.FrameBroker.ErrorCode err;
115             err = Interop.FrameBroker.SendLaunchRequest(handle, appControl.SafeAppControlHandle, resultCallbackMaps[requestId], null, (IntPtr)requestId);
116
117             if (err != Interop.FrameBroker.ErrorCode.None)
118             {
119                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to send launch request");
120             }
121
122             return task.Task;
123         }
124
125         /// <summary>
126         /// Notifies that the animation is started.
127         /// </summary>
128         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
129         /// <exception cref="InvalidOperationException">Thrown when failed because of system error.</exception>
130         internal void StartAnimation()
131         {
132             Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.StartAnimation(context);
133             if (err != Interop.FrameBroker.ErrorCode.None)
134             {
135                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is started");
136             }
137         }
138
139         /// <summary>
140         /// Notifies that the animation is finished.
141         /// </summary>
142         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
143         /// <exception cref="InvalidOperationException">Thrown when failed because of system error.</exception>
144         internal void FinishAnimation()
145         {
146             Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.FinishAnimation(context);
147             if (err != Interop.FrameBroker.ErrorCode.None)
148             {
149                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is finished");
150             }
151         }
152
153         /// <summary>
154         /// Occurs whenever the frame is created.
155         /// </summary>
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         protected virtual void OnFrameCreated()
158         {
159             Log.Warn(logTag, "The OnFrameCreated() is not implemented");
160         }
161
162         /// <summary>
163         /// Occurs Whenever the frame is resumed.
164         /// </summary>
165         /// <param name="frame">The frame data.</param>
166         /// <remarks>
167         /// When the frame has been prepared, this function is called.
168         /// The caller can start animations, To notify that the animation is started, the caller should call StartAnimation().
169         /// After the animation is finished, the caller should call FinishAnimation() to notify.
170         /// </remarks>
171         [EditorBrowsable(EditorBrowsableState.Never)]
172         protected virtual void OnFrameResumed(FrameData frame)
173         {
174             Log.Warn(logTag, "The OnFrameResumed() is not implemented");
175         }
176
177         /// <summary>
178         /// Occurs Whenever the frame is updated.
179         /// </summary>
180         /// <param name="frame">The frame data.</param>
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         protected virtual void OnFrameUpdated(FrameData frame)
183         {
184             Log.Warn(logTag, "The OnFrameUpdated() is not implemented");
185         }
186
187         /// <summary>
188         /// Occurs Whenever the frame is paused.
189         /// </summary>
190         [EditorBrowsable(EditorBrowsableState.Never)]
191         protected virtual void OnFramePaused()
192         {
193             Log.Warn(logTag, "The OnFramePaused() is not implemented");
194         }
195
196         /// <summary>
197         /// Occurs Whenever the frame is destroyed.
198         /// </summary>
199         [EditorBrowsable(EditorBrowsableState.Never)]
200         protected virtual void OnFrameDestroyed()
201         {
202             Log.Warn(logTag, "The OnFrameDestroyed() is not implemented");
203         }
204
205         /// <summary>
206         /// Occurs Whenever the system error is occurred.
207         /// </summary>
208         /// <param name="error">The frame error.</param>
209         [EditorBrowsable(EditorBrowsableState.Never)]
210         protected virtual void OnFrameErred(FrameError error)
211         {
212             Log.Warn(logTag, "The OnFrameErred() is not implemented");
213         }
214
215         private void OnCreateNative(IntPtr context, IntPtr userData)
216         {
217             this.context = context;
218             OnFrameCreated();
219         }
220
221         private void OnResumeNavie(IntPtr context, IntPtr frame, IntPtr userData)
222         {
223             OnFrameResumed(new FrameData(frame));
224         }
225
226         private void OnPauseNative(IntPtr context, IntPtr userData)
227         {
228             OnFramePaused();
229         }
230
231         private void OnDestroyNative(IntPtr context, IntPtr userData)
232         {
233             context = IntPtr.Zero;
234             OnFrameDestroyed();
235         }
236
237         private void OnErrorNative(IntPtr context, int error, IntPtr userData)
238         {
239             context = IntPtr.Zero;
240             OnFrameErred((FrameError)error);
241         }
242
243         private void OnUpdateNative(IntPtr context, IntPtr frame, IntPtr userData)
244         {
245             OnFrameUpdated(new FrameData(frame));
246         }
247
248
249         private Shader CreateShader()
250         {
251             string vertex_shader =
252                 "attribute mediump vec2 aPosition;\n" +
253                 "varying mediump vec2 vTexCoord;\n" +
254                 "uniform highp mat4 uMvpMatrix;\n" +
255                 "uniform mediump vec3 uSize;\n" +
256                 "varying mediump vec2 sTexCoordRect;\n" +
257                 "void main()\n" +
258                 "{\n" +
259                 "gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n" +
260                 "vTexCoord = aPosition + vec2(0.5);\n" +
261                 "}\n";
262
263             string fragment_shader =
264                 "#extension GL_OES_EGL_image_external:require\n" +
265                 "uniform lowp vec4 uColor;\n" +
266                 "varying mediump vec2 vTexCoord;\n" +
267                 "uniform samplerExternalOES sTexture;\n" +
268                 "void main()\n" +
269                 "{\n" +
270                 "gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;\n" +
271                 "}\n";
272
273             return new Shader(vertex_shader, fragment_shader);
274         }
275
276         [StructLayout(LayoutKind.Sequential)]
277         private struct Vec2
278         {
279             float x;
280             float y;
281             public Vec2(float xIn, float yIn)
282             {
283                 x = xIn;
284                 y = yIn;
285             }
286         }
287
288         private struct TexturedQuadVertex
289         {
290             public Vec2 position;
291         };
292
293         private IntPtr RectangleDataPtr()
294         {
295             TexturedQuadVertex vertex1 = new TexturedQuadVertex();
296             TexturedQuadVertex vertex2 = new TexturedQuadVertex();
297             TexturedQuadVertex vertex3 = new TexturedQuadVertex();
298             TexturedQuadVertex vertex4 = new TexturedQuadVertex();
299             vertex1.position = new Vec2(-0.5f, -0.5f);
300             vertex2.position = new Vec2(-0.5f, 0.5f);
301             vertex3.position = new Vec2(0.5f, -0.5f);
302             vertex4.position = new Vec2(0.5f, 0.5f);
303
304             TexturedQuadVertex[] texturedQuadVertexData = new TexturedQuadVertex[4] { vertex1, vertex2, vertex3, vertex4 };
305
306             int lenght = Marshal.SizeOf(vertex1);
307             IntPtr pA = Marshal.AllocHGlobal(lenght * 4);
308
309             for (int i = 0; i < 4; i++)
310             {
311                 Marshal.StructureToPtr(texturedQuadVertexData[i], pA + i * lenght, true);
312             }
313
314             return pA;
315         }
316
317         private Geometry CreateQuadGeometry()
318         {
319             /* Create Property buffer */
320             PropertyValue value = new PropertyValue((int)PropertyType.Vector2);
321             PropertyMap vertexFormat = new PropertyMap();
322             vertexFormat.Add("aPosition", value);
323
324             PropertyBuffer vertexBuffer = new PropertyBuffer(vertexFormat);
325             vertexBuffer.SetData(RectangleDataPtr(), 4);
326
327             Geometry geometry = new Geometry();
328             geometry.AddVertexBuffer(vertexBuffer);
329             geometry.SetType(Geometry.Type.TRIANGLE_STRIP);
330
331             value.Dispose();
332             vertexFormat.Dispose();
333             vertexBuffer.Dispose();
334
335             return geometry;
336         }
337
338         internal Renderer GetRenderer(FrameData data)
339         {
340             Geometry geometry = CreateQuadGeometry();
341             Shader shader = CreateShader();
342             Texture texture = null;
343             renderer = new Renderer(geometry, shader);
344             textureSet = new TextureSet();
345
346             switch (data.Type)
347             {
348                 case FrameData.FrameType.RemoteSurfaceTbmSurface:
349                     if (data.TbmSurface == IntPtr.Zero)
350                     {
351                         geometry.Dispose();
352                         shader.Dispose();
353                         return null;
354                     }
355                     texture = new Texture(data.TbmSurface);
356                     textureSet.SetTexture(0, texture);
357                     renderer.SetTextures(textureSet);
358                     break;
359                 default:
360                     break;
361             }
362
363             texture?.Dispose();
364             geometry.Dispose();
365             shader.Dispose();
366             return renderer;
367         }
368
369         [EditorBrowsable(EditorBrowsableState.Never)]
370         protected virtual void Dispose(bool disposing)
371         {
372             if (!disposed)
373             {
374                 handle.Dispose();
375                 renderer?.Dispose();
376                 textureSet?.Dispose();
377                 disposed = true;
378             }
379         }
380
381         [EditorBrowsable(EditorBrowsableState.Never)]
382         public void Dispose()
383         {
384             Dispose(true);
385
386         }
387     }
388 }