コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="InputGathererThread"/> class.
        /// </summary>
        internal InputGathererThread()
            : base("Input Gatherer", 1000 / Constants.INPUT_FRAMES_PER_SECOND)
        {
            m_commandQueue         = new ThreadSaveQueue <Action>();
            m_gatheredInputFrames  = new ThreadSaveQueue <InputFrame>();
            m_recoveredInputFrames = new ThreadSaveQueue <InputFrame>();

            //m_globalInputHandlers = new List<IInputHandler>();
            m_viewInputHandlers = new Dictionary <IInputEnabledView, List <IInputHandler> >();
        }
コード例 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ResourceDictionary"/> class.
        /// </summary>
        internal ResourceDictionary(EngineDevice device)
        {
            m_device         = device;
            this.DeviceIndex = m_device.DeviceIndex;

            m_lastRenderBlockID = -1;

            m_renderableResources       = new List <IRenderableResource>();
            m_renderableResourcesPublic = new ReadOnlyCollection <IRenderableResource>(m_renderableResources);

            m_resources = new Dictionary <NamedOrGenericKey, ResourceInfo>();
            m_resourcesMarkedForUnloading = new ThreadSaveQueue <Resource>();
        }
コード例 #3
0
ファイル: Scene.cs プロジェクト: Alan-Baylis/SeeingSharp
        /// <summary>
        /// Initializes a new instance of the <see cref="Scene" /> class.
        /// </summary>
        /// <param name="name">The global name of this scene.</param>
        /// <param name="registerOnMessenger">
        /// Do register this scene for application messaging?
        /// If true, then the caller has to ensure that the name is only used once
        /// across the currently executed application.
        /// </param>
        public Scene(
            string name = "",
            bool registerOnMessenger = false)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = DEFAULT_SCENE_NAME;
            }
            this.Name = name;

            m_perFrameData = new CBPerFrame();

            m_transformMode2D     = Graphics2DTransformMode.Custom;
            m_customTransform2D   = Matrix3x2.Identity;
            m_virtualScreenSize2D = new Size2F();

            m_sceneLayers = new List <SceneLayer>();
            m_sceneLayers.Add(new SceneLayer(DEFAULT_LAYER_NAME, this));
            m_sceneLayersPublic = new ReadOnlyCollection <SceneLayer>(m_sceneLayers);

            m_drawing2DLayers = new List <Custom2DDrawingLayer>();

            m_sceneComponents = new SceneComponentFlyweight(this);

            m_asyncInvokesBeforeUpdate          = new ThreadSaveQueue <Action>();
            m_asyncInvokesUpdateBesideRendering = new ThreadSaveQueue <Action>();

            m_registeredResourceDicts = new IndexBasedDynamicCollection <ResourceDictionary>();
            m_registeredViews         = new IndexBasedDynamicCollection <ViewInformation>();
            m_renderParameters        = new IndexBasedDynamicCollection <SceneRenderParameters>();

            this.CachedUpdateState = new SceneRelatedUpdateState(this);

            // Try to initialize this scene object
            InitializeResourceDictionaries(false);

            // Register the scene for ApplicationMessaging
            if (registerOnMessenger)
            {
                m_syncContext = new SceneSynchronizationContext(this);
                m_messenger   = new SeeingSharpMessenger();
                m_messenger.ApplyForGlobalSynchronization(
                    SeeingSharpMessageThreadingBehavior.EnsureMainSyncContextOnSyncCalls,
                    this.Name,
                    m_syncContext);
            }
        }
コード例 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MemoryRenderTarget" /> class.
        /// </summary>
        /// <param name="pixelHeight">Height of the offline render target in pixels.</param>
        /// <param name="pixelWidth">Width of the offline render target in pixels.</param>
        /// <param name="syncContext">Sets the SynchronizationContext which should be used by default.</param>
        public MemoryRenderTarget(int pixelWidth, int pixelHeight, SynchronizationContext syncContext = null)
        {
            //Set confiugration
            m_pixelWidth  = pixelWidth;
            m_pixelHeight = pixelHeight;

            m_renderAwaitors = new ThreadSaveQueue <TaskCompletionSource <object> >();
            if (syncContext == null)
            {
                syncContext = new SynchronizationContext();
            }

            //Create the RenderLoop object
            GraphicsCore.Touch();
            m_renderLoop = new RenderLoop(syncContext, this);
            m_renderLoop.Camera.SetScreenSize(pixelWidth, pixelHeight);
            m_renderLoop.RegisterRenderLoop();
        }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FullscreenRenderTarget" /> class.
        /// </summary>
        /// <param name="outputInfo">The target output monitor.</param>
        /// <param name="initialMode">The initial view mode.</param>
        public FullscreenRenderTarget(EngineOutputInfo outputInfo, EngineOutputModeInfo initialMode = default(EngineOutputModeInfo))
        {
            outputInfo.EnsureNotNull(nameof(outputInfo));

            // Check whether we are inside a win.forms application
            System.Windows.Forms.WindowsFormsSynchronizationContext syncContext = SynchronizationContext.Current
                                                                                  as System.Windows.Forms.WindowsFormsSynchronizationContext;
            if (syncContext == null)
            {
                throw new SeeingSharpException($"{nameof(FullscreenRenderTarget)} muss be created inside a Windows.Forms application context!");
            }
            m_syncContext = syncContext;

            //Set confiugration
            m_targetOutput     = outputInfo;
            m_targetOutputMode = initialMode;
            if (m_targetOutputMode.HostOutput != outputInfo)
            {
                m_targetOutputMode = m_targetOutput.DefaultMode;
            }
            m_renderAwaitors = new ThreadSaveQueue <TaskCompletionSource <object> >();

            // Ensure that graphics is initialized
            GraphicsCore.Touch();

            // Create the dummy form
            m_dummyForm = new DummyForm();
            m_dummyForm.SetStyleCustom(ControlStyles.AllPaintingInWmPaint, true);
            m_dummyForm.SetStyleCustom(ControlStyles.ResizeRedraw, true);
            m_dummyForm.SetStyleCustom(ControlStyles.OptimizedDoubleBuffer, false);
            m_dummyForm.SetStyleCustom(ControlStyles.Opaque, true);
            m_dummyForm.SetStyleCustom(ControlStyles.Selectable, true);
            m_dummyForm.SetDoubleBuffered(false);
            m_dummyForm.MouseEnter      += (sender, eArgs) => Cursor.Hide();
            m_dummyForm.MouseLeave      += (sender, eArgs) => Cursor.Show();
            m_dummyForm.HandleDestroyed += OnDummyForm_HandleDestroyed;
            m_dummyForm.GotFocus        += OnDummyForm_GotFocus;
            m_dummyForm.CreateControl();

            // Create and start the renderloop
            m_renderLoop = new RenderLoop(syncContext, this);
            m_renderLoop.Camera.SetScreenSize(m_targetOutputMode.PixelWidth, m_targetOutputMode.PixelHeight);
            m_renderLoop.RegisterRenderLoop();
        }
コード例 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SceneComponentFlyweight"/> class.
 /// </summary>
 internal SceneComponentFlyweight(Scene owner)
 {
     m_owner              = owner;
     m_componentRequests  = new ThreadSaveQueue <SceneComponentRequest>();
     m_attachedComponents = new List <SceneComponentInfo>();
 }
コード例 #7
0
        /// <summary>
        /// Renders all given scenes using the different devices and performs "UpdateBesideRendering" step.
        /// </summary>
        /// <param name="registeredRenderLoops">The registered render loops on the current pass.</param>
        /// <param name="scenesToRender">All scenes to be updated / rendered.</param>
        /// <param name="devicesInUse">The rendering devices that are in use.</param>
        /// <param name="updateState">Current global update state.</param>
        private void RenderAndUpdateBeside(
            List <RenderLoop> registeredRenderLoops, List <Scene> scenesToRender, List <EngineDevice> devicesInUse, UpdateState updateState)
        {
            using (var perfToken = m_host.BeginMeasureActivityDuration(Constants.PERF_GLOBAL_RENDER_AND_UPDATE_BESIDE))
            {
                ThreadSaveQueue <RenderLoop> invalidRenderLoops = new ThreadSaveQueue <RenderLoop>();

                // Trigger all tasks for 'Update' pass
                Parallel.For(0, devicesInUse.Count + scenesToRender.Count, (actTaskIndex) =>
                {
                    if (actTaskIndex < devicesInUse.Count)
                    {
                        // Render all targets for the current device
                        EngineDevice actDevice = devicesInUse[actTaskIndex];
                        using (var perfTokenInner = m_host.BeginMeasureActivityDuration(string.Format(Constants.PERF_GLOBAL_RENDER_DEVICE, actDevice.AdapterDescription)))
                        {
                            for (int loop = 0; loop < registeredRenderLoops.Count; loop++)
                            {
                                RenderLoop actRenderLoop = registeredRenderLoops[loop];
                                try
                                {
                                    if (actRenderLoop.Device == actDevice)
                                    {
                                        actRenderLoop.Render();
                                    }
                                }
                                catch (Exception)
                                {
                                    // Mark this renderloop as invalid
                                    invalidRenderLoops.Enqueue(actRenderLoop);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Perform updates beside rendering for the current scene
                        int sceneIndex = actTaskIndex - devicesInUse.Count;
                        using (var perfTokenInner = m_host.BeginMeasureActivityDuration(string.Format(Constants.PERF_GLOBAL_UPDATE_BESIDE, sceneIndex)))
                        {
                            Scene actScene = scenesToRender[sceneIndex];
                            SceneRelatedUpdateState actUpdateState = actScene.CachedUpdateState;

                            actUpdateState.OnStartSceneUpdate(actScene, updateState, null);
                            actScene.UpdateBesideRender(actUpdateState);
                        }
                    }
                });

                // Handle all invalid render loops
                if (invalidRenderLoops.HasAny())
                {
                    foreach (var actRenderLoop in invalidRenderLoops.DequeueAll())
                    {
                        DeregisterRenderLoop(actRenderLoop);
                    }
                }

                // Reset camera changed flags
                foreach (RenderLoop actRenderLoop in registeredRenderLoops)
                {
                    actRenderLoop.Camera.StateChanged = false;
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Updates the scene's and prepares all views for rendering.
        /// </summary>
        /// <param name="renderingRenderLoops">The registered render loops on the current pass.</param>
        /// <param name="scenesToRender">All scenes to be updated / rendered.</param>
        /// <param name="devicesInUse">The rendering devices that are in use.</param>
        /// <param name="inputFrames">All InputFrames gathered during last render.</param>
        /// <param name="updateState">Current global update state.</param>
        private async Task UpdateAndPrepareRendering(List <RenderLoop> renderingRenderLoops, List <Scene> scenesToRender, List <EngineDevice> devicesInUse, IEnumerable <InputFrame> inputFrames, UpdateState updateState)
        {
            using (var perfToken = m_host.BeginMeasureActivityDuration(Constants.PERF_GLOBAL_UPDATE_AND_PREPARE))
            {
                List <Action> additionalContinuationActions     = new List <Action>();
                object        additionalContinuationActionsLock = new object();

                // Trigger all tasks for preparing views
                List <Task <List <Action> > > prepareRenderTasks = new List <Task <List <Action> > >(renderingRenderLoops.Count);
                for (int actDeviceIndex = 0; actDeviceIndex < devicesInUse.Count; actDeviceIndex++)
                {
                    EngineDevice actDevice = devicesInUse[actDeviceIndex];
                    for (int loop = 0; loop < renderingRenderLoops.Count; loop++)
                    {
                        RenderLoop actRenderLoop = renderingRenderLoops[loop];
                        if (actRenderLoop.Device == actDevice)
                        {
                            // Call prepare render and wait for the answer
                            //  => Error handling is a bit tricky..
                            //     Errors are catched by the continuation action
                            var actTask = actRenderLoop.PrepareRenderAsync();
                            prepareRenderTasks.Add(actTask.ContinueWith((givenTask) =>
                            {
                                if (!givenTask.IsFaulted)
                                {
                                    return(givenTask.Result);
                                }
                                else
                                {
                                    // Deregister this RenderLoop
                                    lock (additionalContinuationActionsLock)
                                    {
                                        additionalContinuationActions.Add(() =>
                                        {
                                            this.DeregisterRenderLoop(actRenderLoop);
                                            renderingRenderLoops.Remove(actRenderLoop);
                                        });
                                    }

                                    return(new List <Action>());
                                }
                            }));
                        }
                    }
                }

                // Handle initial configuration of render loops (=> No current device)
                for (int loop = 0; loop < renderingRenderLoops.Count; loop++)
                {
                    RenderLoop actRenderLoop = renderingRenderLoops[loop];
                    if (actRenderLoop.Device == null)
                    {
                        try
                        {
                            Task <List <Action> > actPrepareRenderTask = actRenderLoop.PrepareRenderAsync();
                            await actPrepareRenderTask;

                            lock (additionalContinuationActionsLock)
                            {
                                additionalContinuationActions.AddRange(actPrepareRenderTask.Result);
                            }
                        }
                        catch (Exception)
                        {
                            // Deregister this RenderLoop
                            lock (additionalContinuationActionsLock)
                            {
                                additionalContinuationActions.Add(() =>
                                {
                                    this.DeregisterRenderLoop(actRenderLoop);
                                    renderingRenderLoops.Remove(actRenderLoop);
                                });
                            }
                        }
                    }
                }

                // Update all scenes
                ThreadSaveQueue <Exception> exceptionsDuringUpdate = new ThreadSaveQueue <Exception>();
                Parallel.For(0, scenesToRender.Count, (actTaskIndex) =>
                {
                    try
                    {
                        using (var perfToken2 = m_host.BeginMeasureActivityDuration(
                                   string.Format(Constants.PERF_GLOBAL_UPDATE_SCENE, actTaskIndex)))
                        {
                            Scene actScene = scenesToRender[actTaskIndex];
                            SceneRelatedUpdateState actUpdateState = actScene.CachedUpdateState;

                            actUpdateState.OnStartSceneUpdate(actScene, updateState, inputFrames);

                            actScene.Update(actUpdateState);
                        }
                    }
                    catch (Exception ex)
                    {
                        exceptionsDuringUpdate.Enqueue(ex);
                    }
                });

                // Await synchronizations with the view(s)
                if (prepareRenderTasks.Count > 0)
                {
                    await Task.WhenAll(prepareRenderTasks.ToArray());
                }

                // Throw exceptions if any occurred during scene update
                //  => This would be a fatal exception, so throw up to main loop
                if (exceptionsDuringUpdate.HasAny())
                {
                    throw new AggregateException("Error(s) during Scene update!", exceptionsDuringUpdate.DequeueAll().ToArray());
                }

                // Trigger all continuation actions returned by the previously executed prepare tasks
                foreach (var actPrepareTasks in prepareRenderTasks)
                {
                    if (actPrepareTasks.IsFaulted || actPrepareTasks.IsCanceled)
                    {
                        continue;
                    }
                    foreach (Action actContinuationAction in actPrepareTasks.Result)
                    {
                        actContinuationAction();
                    }
                }
                foreach (var actAction in additionalContinuationActions)
                {
                    actAction();
                }

                // Reset all dummy flags before rendering
                foreach (var actRenderLoop in renderingRenderLoops)
                {
                    actRenderLoop.ResetFlagsBeforeRendering();
                }

                // Unload all derigistered RenderLoops
                await UpdateRenderLoopRegistrationsAsync(renderingRenderLoops);
            }
        }