private void ReconcileTrailingMarkers() { // there is a chance that 'lastCompleteBlock' may have an IL marker // placed at the end of it such that block offset of the marker points // to the next byte *after* the block is closed. In this case the marker // should be moved to the next block if (_lastCompleteBlock != null && _lastCompleteBlock.BranchCode == ILOpCode.Nop && _lastCompleteBlock.LastILMarker >= 0 && _allocatedILMarkers[_lastCompleteBlock.LastILMarker].BlockOffset == _lastCompleteBlock.RegularInstructionsLength) { int startMarker = -1; int endMarker = -1; while (_lastCompleteBlock.LastILMarker >= 0 && _allocatedILMarkers[_lastCompleteBlock.LastILMarker].BlockOffset == _lastCompleteBlock.RegularInstructionsLength) { Debug.Assert((startMarker < 0) || (startMarker == (_lastCompleteBlock.LastILMarker + 1))); startMarker = _lastCompleteBlock.LastILMarker; if (endMarker < 0) { endMarker = _lastCompleteBlock.LastILMarker; } _lastCompleteBlock.RemoveTailILMarker(_lastCompleteBlock.LastILMarker); } BasicBlock current = this.GetCurrentBlock(); for (int marker = startMarker; marker <= endMarker; marker++) { current.AddILMarker(marker); _allocatedILMarkers[marker] = new ILMarker() { BlockOffset = (int)current.RegularInstructionsLength, AbsoluteOffset = -1 }; } } }
public ILMarkerWrapper(ILMarker source, ILPanelEditor editor, string path, string name = null, string label = null) : base(source, editor, path, BuildName(name, editor.Panel, source, "Marker"), label) { this.source = source; fill = new ILTrianglesWrapper(source.Fill, editor, Path, ILMarker.DefaultFillTag, "Fill"); border = new ILLinesWrapper(source.Border, editor, Path, ILMarker.DefaultBorderTag, "Border"); }
/// <summary> /// [internal] constructor - do not use this! Use ILPanel.Graphs.Add...() instead! /// </summary> /// <param name="panel">panel hosting the scene</param> /// <param name="XData">x data array</param> /// <param name="YData">y data array</param> /// <param name="clippingContainer">hosting panels clipping data</param> public ILPlot2DGraph(ILPanel panel, ILBaseArray XData, ILBaseArray YData, ILClippingData clippingContainer) : base(panel, clippingContainer) { if (!XData.IsVector) { throw new ILArgumentException("Plot2D: supplied data must be a real vector!"); } if (!YData.IsVector) { throw new ILArgumentException("Plot2D: XData and YData must be real vectors!"); } if (YData.Length != XData.Length) { throw new ILArgumentException("Plot2D: XData and YData must have the same length!"); } int pos = 0; ILArray <float> dataX, dataY; C4bV3f vert = new C4bV3f(); if (XData is ILArray <float> ) { dataX = (ILArray <float>)XData; } else { dataX = ILMath.tosingle(XData); } if (YData is ILArray <float> ) { dataY = (ILArray <float>)YData; } else { dataY = ILMath.tosingle(YData); } m_vertices = new C4bV3f[dataX.Length + 1]; m_vertexCount = m_vertices.Length; m_startID = m_vertexCount - 1; m_updateCount = 0; m_properties = new ILLineProperties(); m_properties.Color = Color.DarkBlue; m_properties.Changed += new EventHandler(m_properties_Changed); foreach (float val in dataX.Values) { vert.Position = new ILPoint3Df(val, dataY.GetValue(pos), 0); vert.Color = m_properties.Color; m_vertices[pos++] = vert; } m_marker = new ILMarker(panel); m_marker.Changed += new EventHandler(m_marker_Changed); m_graphType = GraphType.Plot2D; updateClipping(); }
private void SetupMarkerStyle(ILMarker marker) { GL.PointSize(marker.Size); GL.Color3(marker.Color); switch (m_style) { case MarkerStyle.Dot: GL.Enable(EnableCap.PointSmooth); break; case MarkerStyle.Square: GL.Disable(EnableCap.PointSmooth); break; case MarkerStyle.None: GL.PointSize(0.0f); break; default: throw new NotImplementedException(); } }
/// <summary> /// [internal] constructor - do not use this! Use ILPanel.Graphs.Add...() instead! /// </summary> /// <param name="panel">panel hosting the scene</param> /// <param name="sourceArray">data array</param> /// <param name="clippingContainer">hosting panels clipping data</param> public ILPlot2DGraph(ILPanel panel, ILBaseArray sourceArray, ILClippingData clippingContainer) : base(panel, clippingContainer) { if (object.Equals(sourceArray, null) || !sourceArray.IsVector || !sourceArray.IsNumeric) { throw new ILArgumentException("Plot2D: supplied data must be numeric (real valued) vector!"); } int pos = 0; ILArray <float> data; C4bV3f vert = new C4bV3f(); if (sourceArray is ILArray <float> ) { data = (ILArray <float>)sourceArray; } else { data = ILMath.tosingle(sourceArray); } m_vertices = new C4bV3f[data.Length + 1]; m_vertexCount = m_vertices.Length; m_updateCount = 0; m_startID = 0; m_properties = new ILLineProperties(); m_properties.Color = Color.DarkBlue; m_properties.Changed += new EventHandler(m_properties_Changed); foreach (float val in data.Values) { vert.Position = new ILPoint3Df(pos, val, 0); vert.Color = Color.Red; m_vertices[pos++] = vert; } m_marker = new ILMarker(panel); m_marker.Changed += new EventHandler(m_properties_Changed); m_graphType = GraphType.Plot2D; m_localClipping.Set(new ILPoint3Df(0, data.MinValue, 0), new ILPoint3Df(data.Length - 1, data.MaxValue, 0)); }
private void RealizeBlocks() { // drop dead code. // We do not want to deal with unreachable code even when not optimizing. // sometimes dead code may have subtle verification violations // for example illegal fall-through in unreachable code is still illegal, // but compiler will not enforce returning from dead code. // it is easier to just remove dead code than make sure it is all valid MarkReachableBlocks(); RewriteSpecialBlocks(); DropUnreachableBlocks(); if (_optimizations == OptimizationLevel.Release && OptimizeLabels()) { // redo unreachable code elimination if some labels were optimized // as that could result in more dead code. MarkAllBlocksUnreachable(); MarkReachableBlocks(); DropUnreachableBlocks(); } // some gotos must become leaves RewriteBranchesAcrossExceptionHandlers(); // now we can compute block offsets and adjust branches while (ComputeOffsetsAndAdjustBranches()) { // if branches were optimized, we may have more unreachable code // redo unreachable code elimination and if anything was dropped redo adjusting. MarkAllBlocksUnreachable(); MarkReachableBlocks(); if (!DropUnreachableBlocks()) { // nothing was dropped, we are done adjusting break; } } // Now linearize everything with computed offsets. var writer = Cci.PooledBlobBuilder.GetInstance(); for (var block = leaderBlock; block != null; block = block.NextBlock) { // If the block has any IL markers, we can calculate their real IL offsets now int blockFirstMarker = block.FirstILMarker; if (blockFirstMarker >= 0) { int blockLastMarker = block.LastILMarker; Debug.Assert(blockLastMarker >= blockFirstMarker); for (int i = blockFirstMarker; i <= blockLastMarker; i++) { int blockOffset = _allocatedILMarkers[i].BlockOffset; int absoluteOffset = writer.Count + blockOffset; _allocatedILMarkers[i] = new ILMarker() { BlockOffset = blockOffset, AbsoluteOffset = absoluteOffset }; } } block.RegularInstructions?.WriteContentTo(writer); switch (block.BranchCode) { case ILOpCode.Nop: break; case ILOpCode.Switch: // switch (N, t1, t2... tN) // IL ==> ILOpCode.Switch < unsigned int32 > < int32 >... < int32 > WriteOpCode(writer, ILOpCode.Switch); var switchBlock = (SwitchBlock)block; writer.WriteUInt32(switchBlock.BranchesCount); int switchBlockEnd = switchBlock.Start + switchBlock.TotalSize; var blockBuilder = ArrayBuilder <BasicBlock> .GetInstance(); switchBlock.GetBranchBlocks(blockBuilder); foreach (var branchBlock in blockBuilder) { writer.WriteInt32(branchBlock.Start - switchBlockEnd); } blockBuilder.Free(); break; default: WriteOpCode(writer, block.BranchCode); if (block.BranchLabel != null) { int target = block.BranchBlock.Start; int curBlockEnd = block.Start + block.TotalSize; int offset = target - curBlockEnd; if (block.BranchCode.GetBranchOperandSize() == 1) { sbyte btOffset = (sbyte)offset; Debug.Assert(btOffset == offset); writer.WriteSByte(btOffset); } else { writer.WriteInt32(offset); } } break; } } this.RealizedIL = writer.ToImmutableArray(); writer.Free(); RealizeSequencePoints(); this.RealizedExceptionHandlers = _scopeManager.GetExceptionHandlerRegions(); }
private void RealizeBlocks() { // drop dead code. // We do not want to deal with unreachable code even when not optimizing. // sometimes dead code may have subtle verification violations // for example illegal fall-through in unreachable code is still illegal, // but compiler will not enforce returning from dead code. // it is easier to just remove dead code than make sure it is all valid MarkReachableBlocks(); RewriteSpecialBlocks(); DropUnreachableBlocks(); if (_optimizations == OptimizationLevel.Release && OptimizeLabels()) { // redo unreachable code elimination if some labels were optimized // as that could result in more dead code. MarkAllBlocksUnreachable(); MarkReachableBlocks(); DropUnreachableBlocks(); } // some gotos must become leaves RewriteBranchesAcrossExceptionHandlers(); // now we can compute block offsets and adjust branches while (ComputeOffsetsAndAdjustBranches()) { // if branches were optimized, we may have more unreachable code // redo unreachable code elimination and if anything was dropped redo adjusting. MarkAllBlocksUnreachable(); MarkReachableBlocks(); if (!DropUnreachableBlocks()) { // nothing was dropped, we are done adjusting break; } } // Now linearize everything with computed offsets. var realizedIlBitStream = Cci.MemoryStream.GetInstance(); var writer = new Cci.BinaryWriter(realizedIlBitStream); for (var block = leaderBlock; block != null; block = block.NextBlock) { // If the block has any IL markers, we can calculate their real IL offsets now int blockFirstMarker = block.FirstILMarker; if (blockFirstMarker >= 0) { int blockLastMarker = block.LastILMarker; Debug.Assert(blockLastMarker >= blockFirstMarker); for (int i = blockFirstMarker; i <= blockLastMarker; i++) { int blockOffset = _allocatedILMarkers[i].BlockOffset; int absoluteOffset = (int)realizedIlBitStream.Position + blockOffset; _allocatedILMarkers[i] = new ILMarker() { BlockOffset = blockOffset, AbsoluteOffset = absoluteOffset }; } } block.RegularInstructions?.WriteTo(realizedIlBitStream); switch (block.BranchCode) { case ILOpCode.Nop: break; case ILOpCode.Switch: // switch (N, t1, t2... tN) // IL ==> ILOpCode.Switch < unsigned int32 > < int32 >... < int32 > WriteOpCode(writer, ILOpCode.Switch); var switchBlock = (SwitchBlock)block; writer.WriteUint(switchBlock.BranchesCount); int switchBlockEnd = switchBlock.Start + switchBlock.TotalSize; var blockBuilder = ArrayBuilder<BasicBlock>.GetInstance(); switchBlock.GetBranchBlocks(blockBuilder); foreach (var branchBlock in blockBuilder) { writer.WriteInt(branchBlock.Start - switchBlockEnd); } blockBuilder.Free(); break; default: WriteOpCode(writer, block.BranchCode); if (block.BranchLabel != null) { int target = block.BranchBlock.Start; int curBlockEnd = block.Start + block.TotalSize; int offset = target - curBlockEnd; if (block.BranchCode.BranchOperandSize() == 1) { sbyte btOffset = (sbyte)offset; Debug.Assert(btOffset == offset); writer.WriteSbyte(btOffset); } else { writer.WriteInt(offset); } } break; } } this.RealizedIL = realizedIlBitStream.ToArray(); realizedIlBitStream.Free(); RealizeSequencePoints(); this.RealizedExceptionHandlers = _scopeManager.GetExceptionHandlerRegions(); }
internal override void Draw(ILRenderProperties p, ILMarker marker, C4bV3f[] vertices, int startID, int vertCount) { if (vertCount == 0 && vertCount != -1) { return; } string texKey = Hash(); ILTextureData texData; if (!m_panel.TextureManager.Exists(texKey)) { storeBitmap(m_bitmap); } texData = m_panel.TextureManager.GetTextureItem(texKey, true); System.Diagnostics.Debug.Assert(texData != null, "The texture key for the bitmap was expected to exist in texture storage, but it was not found!"); // prepare for plotting GL.Color3(marker.Color); GL.PushAttrib(AttribMask.AllAttribBits); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); RectangleF rectF = texData.TextureRectangle; float w, h; if (vertCount > 0) { #region draw textured points (slow version: textured quads) #region determine size for markers in world coords (graph limits) ILClippingData clip = m_panel.Limits; float s05x; float s05y; //if (m_marker.) s05x = Math.Abs(marker.Size * clip.WidthF / (m_panel.ClientSize.Width)); s05y = Math.Abs(marker.Size * clip.HeightF / (m_panel.ClientSize.Height)); #endregion // draw all markers using quads. // this is slow! Todo: replace by point sprites! GL.Begin(BeginMode.Quads); for (int i = 0; i < vertCount; i++) { w = vertices[i].Position.X; h = vertices[i].Position.Y; if (m_panel.ClipViewData && (w < clip.XMin || w > clip.XMax || h < clip.YMin || h > clip.YMax)) { continue; } w -= s05x; h -= s05y; GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex2(w, h); // ul GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex2(w, h + 2 * s05y); // bl w += 2 * s05x; GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex2(w, h + 2 * s05y); // br GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex2(w, h); // tr } GL.End(); #endregion } else if (vertCount == -1) { #region render to legend // draw all markers using quads. // this is slow! Todo: replace by point sprites! GL.Begin(BeginMode.Quads); w = vertices[0].XPosition - m_bitmap.Width / 2; h = vertices[0].YPosition - m_bitmap.Height / 2; GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex2(w, h); // ul GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex2(w, h + m_bitmap.Height); // bl w += m_bitmap.Width; GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex2(w, h + m_bitmap.Height); // br GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex2(w, h); // tr GL.End(); #endregion } GL.PopAttrib(); }
internal override void Draw(ILRenderProperties p, ILMarker marker, C4bV3f[] vertices, int startID, int vertCount) { // some implementations need to know we are drawing in // screen coords, vertcount give the signal: -1 if (vertCount == 0 || vertCount < -1) { return; } if (m_style != MarkerStyle.None) { if (m_style == MarkerStyle.Dot || m_style == MarkerStyle.Square) { SetupMarkerStyle(marker); unsafe { fixed(C4bV3f *pVertArr = vertices) { //GL.TexCoord2(0.5,0.5); GL.InterleavedArrays(InterleavedArrayFormat.V2f, 0, (IntPtr)pVertArr); GL.DrawArrays(BeginMode.Points, 0, Math.Abs(vertCount)); } } } else { #region draw textured points (slow version: textured quads) string markerTexKey = Hash(); ILTextureData texData; if (!m_panel.TextureManager.Exists(markerTexKey)) { CacheMarkerBitmap(); } texData = m_panel.TextureManager.GetTextureItem(markerTexKey, true); System.Diagnostics.Debug.Assert(texData != null, "The texture for marker was expected to exist in texture storage, but it was not found!"); // prepare for plotting GL.Color3(marker.Color); GL.PushAttrib(AttribMask.AllAttribBits); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Disable(EnableCap.DepthTest); RectangleF rectF = texData.TextureRectangle; float w, h; if (vertCount > 0) { #region determine size for markers in world coords (graph limits) ILClippingData clip = m_panel.Limits; float s05x; float s05y; //if (m_marker.) s05x = Math.Abs(marker.Size * clip.WidthF / (m_panel.ClientSize.Width)); s05y = Math.Abs(marker.Size * clip.HeightF / (m_panel.ClientSize.Height)); #endregion // draw all markers using quads. // this is slow! Todo: replace by point sprites! GL.Begin(BeginMode.Quads); for (int i = 0; i < vertCount; i++) { w = vertices[i].XPosition; h = vertices[i].YPosition; if (m_panel.ClipViewData && (w < clip.XMin || w > clip.XMax || h < clip.YMin || h > clip.YMax)) { continue; } w -= s05x; h -= s05y; GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex2(w, h); // ul GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex2(w, h + 2 * s05y); // bl w += 2 * s05x; GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex2(w, h + 2 * s05y); // br GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex2(w, h); // tr } GL.End(); } else if (vertCount == -1) { GL.Begin(BeginMode.Quads); w = vertices[0].XPosition - marker.Size / 2; h = vertices[0].XPosition - marker.Size / 2; GL.TexCoord2(rectF.Left, rectF.Top); GL.Vertex2(w, h); // ul GL.TexCoord2(rectF.Left, rectF.Bottom); GL.Vertex2(w, h + marker.Size); // bl w += marker.Size; GL.TexCoord2(rectF.Right, rectF.Bottom); GL.Vertex2(w, h + marker.Size); // br GL.TexCoord2(rectF.Right, rectF.Top); GL.Vertex2(w, h); // tr GL.End(); } GL.PopAttrib(); #endregion } } }