2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
28 /// Represents the Frame Broker.
30 internal abstract class FrameBrokerBase : IDisposable
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;
40 private Renderer renderer;
41 private TextureSet textureSet;
44 /// Initializes the FrameBroker class.
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)
53 Interop.FrameBroker.ErrorCode err;
57 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
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);
67 err = Interop.FrameBroker.Create(window.GetNativeWindowHandler(), ref callbacks, IntPtr.Zero, out handle);
68 if (err != Interop.FrameBroker.ErrorCode.None)
70 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to create frame broker handle");
75 /// Sends the launch request asynchronously.
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.
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)
93 if (appControl == null)
95 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
98 var task = new TaskCompletionSource<FrameBrokerBaseResult>();
101 lock (resultCallbackMaps)
103 requestId = resultId++;
104 resultCallbackMaps[requestId] = (handle, result, userData) =>
106 task.SetResult((FrameBrokerBaseResult)result);
107 lock (resultCallbackMaps)
109 resultCallbackMaps.Remove((int)userData);
114 Interop.FrameBroker.ErrorCode err;
115 err = Interop.FrameBroker.SendLaunchRequest(handle, appControl.SafeAppControlHandle, resultCallbackMaps[requestId], null, (IntPtr)requestId);
117 if (err != Interop.FrameBroker.ErrorCode.None)
119 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to send launch request");
126 /// Notifies that the animation is started.
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()
132 Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.StartAnimation(context);
133 if (err != Interop.FrameBroker.ErrorCode.None)
135 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is started");
140 /// Notifies that the animation is finished.
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()
146 Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.FinishAnimation(context);
147 if (err != Interop.FrameBroker.ErrorCode.None)
149 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is finished");
154 /// Occurs whenever the frame is created.
156 [EditorBrowsable(EditorBrowsableState.Never)]
157 protected virtual void OnFrameCreated()
159 Log.Warn(logTag, "The OnFrameCreated() is not implemented");
163 /// Occurs Whenever the frame is resumed.
165 /// <param name="frame">The frame data.</param>
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.
171 [EditorBrowsable(EditorBrowsableState.Never)]
172 protected virtual void OnFrameResumed(FrameData frame)
174 Log.Warn(logTag, "The OnFrameResumed() is not implemented");
178 /// Occurs Whenever the frame is updated.
180 /// <param name="frame">The frame data.</param>
181 [EditorBrowsable(EditorBrowsableState.Never)]
182 protected virtual void OnFrameUpdated(FrameData frame)
184 Log.Warn(logTag, "The OnFrameUpdated() is not implemented");
188 /// Occurs Whenever the frame is paused.
190 [EditorBrowsable(EditorBrowsableState.Never)]
191 protected virtual void OnFramePaused()
193 Log.Warn(logTag, "The OnFramePaused() is not implemented");
197 /// Occurs Whenever the frame is destroyed.
199 [EditorBrowsable(EditorBrowsableState.Never)]
200 protected virtual void OnFrameDestroyed()
202 Log.Warn(logTag, "The OnFrameDestroyed() is not implemented");
206 /// Occurs Whenever the system error is occurred.
208 /// <param name="error">The frame error.</param>
209 [EditorBrowsable(EditorBrowsableState.Never)]
210 protected virtual void OnFrameErred(FrameError error)
212 Log.Warn(logTag, "The OnFrameErred() is not implemented");
215 private void OnCreateNative(IntPtr context, IntPtr userData)
217 this.context = context;
221 private void OnResumeNavie(IntPtr context, IntPtr frame, IntPtr userData)
223 OnFrameResumed(new FrameData(frame));
226 private void OnPauseNative(IntPtr context, IntPtr userData)
231 private void OnDestroyNative(IntPtr context, IntPtr userData)
233 context = IntPtr.Zero;
237 private void OnErrorNative(IntPtr context, int error, IntPtr userData)
239 context = IntPtr.Zero;
240 OnFrameErred((FrameError)error);
243 private void OnUpdateNative(IntPtr context, IntPtr frame, IntPtr userData)
245 OnFrameUpdated(new FrameData(frame));
249 private Shader CreateShader()
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" +
259 "gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n" +
260 "vTexCoord = aPosition + vec2(0.5);\n" +
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" +
270 "gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;\n" +
273 return new Shader(vertex_shader, fragment_shader);
276 [StructLayout(LayoutKind.Sequential)]
281 public Vec2(float xIn, float yIn)
288 private struct TexturedQuadVertex
290 public Vec2 position;
293 private IntPtr RectangleDataPtr()
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);
304 TexturedQuadVertex[] texturedQuadVertexData = new TexturedQuadVertex[4] { vertex1, vertex2, vertex3, vertex4 };
306 int lenght = Marshal.SizeOf(vertex1);
307 IntPtr pA = Marshal.AllocHGlobal(lenght * 4);
309 for (int i = 0; i < 4; i++)
311 Marshal.StructureToPtr(texturedQuadVertexData[i], pA + i * lenght, true);
317 private Geometry CreateQuadGeometry()
319 /* Create Property buffer */
320 PropertyValue value = new PropertyValue((int)PropertyType.Vector2);
321 PropertyMap vertexFormat = new PropertyMap();
322 vertexFormat.Add("aPosition", value);
324 PropertyBuffer vertexBuffer = new PropertyBuffer(vertexFormat);
325 vertexBuffer.SetData(RectangleDataPtr(), 4);
327 Geometry geometry = new Geometry();
328 geometry.AddVertexBuffer(vertexBuffer);
329 geometry.SetType(Geometry.Type.TRIANGLE_STRIP);
332 vertexFormat.Dispose();
333 vertexBuffer.Dispose();
338 internal Renderer GetRenderer(FrameData data)
340 Geometry geometry = CreateQuadGeometry();
341 Shader shader = CreateShader();
342 Texture texture = null;
343 renderer = new Renderer(geometry, shader);
344 textureSet = new TextureSet();
348 case FrameData.FrameType.RemoteSurfaceTbmSurface:
349 if (data.TbmSurface == IntPtr.Zero)
355 texture = new Texture(data.TbmSurface);
356 textureSet.SetTexture(0, texture);
357 renderer.SetTextures(textureSet);
369 [EditorBrowsable(EditorBrowsableState.Never)]
370 protected virtual void Dispose(bool disposing)
376 textureSet?.Dispose();
381 [EditorBrowsable(EditorBrowsableState.Never)]
382 public void Dispose()