From 37570a2ebed6dfa7ebabc665c688af14b55a894a Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Fri, 19 May 2017 21:33:37 +0200 Subject: [PATCH] CrowMonitor tread logger --- Crow.csproj | 1 + src/CrowMonitor.cs | 61 +++++++ src/CrowThread.cs | 2 +- src/GraphicObjects/GraphicObject.cs | 89 +++++----- src/GraphicObjects/Image.cs | 6 +- src/GraphicObjects/MessageBox.cs | 26 +-- src/GraphicObjects/TemplatedGroup.cs | 24 +-- src/Interface.cs | 98 ++++++----- testDrm/Main.cs | 106 +++++++++++- testDrm/src/Application.cs | 31 ++-- testDrm/src/Egl/Context.cs | 3 - testDrm/src/Egl/Surface.cs | 25 ++- testDrm/src/Linux/DRI.cs | 235 +++++++++++--------------- testDrm/src/Linux/DRI/Connector.cs | 2 +- testDrm/src/Linux/DRI/Encoder.cs | 2 +- testDrm/src/Linux/GBM/BufferObject.cs | 2 +- testDrm/testDrm.csproj | 10 +- testDrm/testThreadMonitor.cs | 90 ++++++++++ testDrm/ui/0.crow | 7 +- testDrm/ui/1.crow | 2 + testDrm/ui/2.crow | 95 +++++++++++ testDrm/ui/colorItem.crow | 10 ++ testDrm/ui/menu.crow | 2 +- 23 files changed, 635 insertions(+), 294 deletions(-) create mode 100644 src/CrowMonitor.cs create mode 100644 testDrm/testThreadMonitor.cs create mode 100755 testDrm/ui/1.crow create mode 100755 testDrm/ui/2.crow create mode 100755 testDrm/ui/colorItem.crow diff --git a/Crow.csproj b/Crow.csproj index 3e8bcd55..9d48069c 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -214,6 +214,7 @@ + diff --git a/src/CrowMonitor.cs b/src/CrowMonitor.cs new file mode 100644 index 00000000..53b20070 --- /dev/null +++ b/src/CrowMonitor.cs @@ -0,0 +1,61 @@ +// +// CrowMonitor.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2013-2017 Jean-Philippe Bruyère +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Threading; +using System.Diagnostics; + +namespace Crow +{ + public class NamedMutex { + public string Name; + public NamedMutex (string name){ + Name = name; + } + } + public static class CrowMonitor + { + public static Stopwatch timer = Stopwatch.StartNew(); + + public static bool TryEnter (NamedMutex mutex, string ctxName = "?"){ + Console.WriteLine("{3}:TRY LCK:{0} => {1} ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks); + bool locking = Monitor.TryEnter (mutex); + if (locking) + Console.WriteLine("{2}:\tLOCKED :{0} => {1} mutex", Thread.CurrentThread.Name, mutex.Name, timer.ElapsedTicks); + return locking; + + } + public static void Enter (NamedMutex mutex, string ctxName = "?") { + Console.WriteLine("{3}:WAIT :{0} => {1} ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks); + Monitor.Enter (mutex); + Console.WriteLine("{3}:\tLOCKED :{0} => {1} mutex ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks); + } + public static void Exit (NamedMutex mutex) { + Monitor.Exit (mutex); + Console.WriteLine("{2}:\tRELEASE:{0} => {1} mutex", Thread.CurrentThread.Name, mutex.Name, timer.ElapsedTicks); + } + } +} + diff --git a/src/CrowThread.cs b/src/CrowThread.cs index ece87fa8..1f0b1d76 100644 --- a/src/CrowThread.cs +++ b/src/CrowThread.cs @@ -33,7 +33,7 @@ namespace Crow /// Thread monitored by current interface with Finished event when state==Stopped /// public class CrowThread { - Thread thread; + internal Thread thread; public event EventHandler Finished; public GraphicObject Host; public CrowThread (GraphicObject host, ThreadStart start){ diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 5de94f60..559719a9 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -40,6 +40,7 @@ namespace Crow { public class GraphicObject : ILayoutable, IValueChange { + internal NamedMutex mutex = new NamedMutex("GRAPHIC OBJECT"); internal static ulong currentUid = 0; internal ulong uid = 0; @@ -162,8 +163,9 @@ namespace Crow if (parent == value) return; DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value); - lock (this) - parent = value; + CrowMonitor.Enter (mutex, "set parent of object"); + parent = value; + CrowMonitor.Exit (mutex); onParentChanged (this, e); } @@ -887,12 +889,12 @@ namespace Crow public virtual void RegisterForLayouting(LayoutingType layoutType){ if (Parent == null) return; - lock (CurrentInterface.LayoutMutex) { - //prevent queueing same LayoutingType for this - layoutType &= (~RegisteredLayoutings); + CrowMonitor.Enter (CurrentInterface.LayoutMutex, "register for layouting"); + //prevent queueing same LayoutingType for this + layoutType &= (~RegisteredLayoutings); - if (layoutType == LayoutingType.None) - return; + if (layoutType != LayoutingType.None) { + //dont set position for stretched item if (Width == Measure.Stretched) layoutType &= (~LayoutingType.X); @@ -909,21 +911,21 @@ namespace Crow // //prevent queueing same LayoutingType for this // layoutType &= (~RegisteredLayoutings); - if (layoutType == LayoutingType.None) - return; - - //enqueue LQI LayoutingTypes separately - if (layoutType.HasFlag (LayoutingType.Width)) - CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); - if (layoutType.HasFlag (LayoutingType.Height)) - CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); - if (layoutType.HasFlag (LayoutingType.X)) - CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); - if (layoutType.HasFlag (LayoutingType.Y)) - CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); - if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) - CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); + if (layoutType != LayoutingType.None) { + //enqueue LQI LayoutingTypes separately + if (layoutType.HasFlag (LayoutingType.Width)) + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); + if (layoutType.HasFlag (LayoutingType.Height)) + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); + if (layoutType.HasFlag (LayoutingType.X)) + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); + if (layoutType.HasFlag (LayoutingType.Y)) + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); + if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) + CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); + } } + CrowMonitor.Exit (CurrentInterface.LayoutMutex); } /// trigger dependant sizing component update @@ -1154,33 +1156,36 @@ namespace Crow //TODO:this test should not be necessary if (Slot.Height < 0 || Slot.Width < 0 || parent == null) return; - lock (this) { - if (cacheEnabled) { - if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize) - cacheEnabled = false; - } + + CrowMonitor.Enter (mutex, "Paint"); - if (cacheEnabled) { - if (IsDirty) - RecreateCache (); + if (cacheEnabled) { + if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize) + cacheEnabled = false; + } - UpdateCache (ctx); - if (!isEnabled) - paintDisabled (ctx, Slot + Parent.ClientRectangle.Position); - } else { - Rectangle rb = Slot + Parent.ClientRectangle.Position; - ctx.Save (); + if (cacheEnabled) { + if (IsDirty) + RecreateCache (); - ctx.Translate (rb.X, rb.Y); + UpdateCache (ctx); + if (!isEnabled) + paintDisabled (ctx, Slot + Parent.ClientRectangle.Position); + } else { + Rectangle rb = Slot + Parent.ClientRectangle.Position; + ctx.Save (); - onDraw (ctx); - if (!isEnabled) - paintDisabled (ctx, Slot); + ctx.Translate (rb.X, rb.Y); - ctx.Restore (); - } - LastPaintedSlot = Slot; + onDraw (ctx); + if (!isEnabled) + paintDisabled (ctx, Slot); + + ctx.Restore (); } + LastPaintedSlot = Slot; + + CrowMonitor.Exit (mutex); } void paintDisabled(Context gr, Rectangle rb){ gr.Operator = Operator.Xor; diff --git a/src/GraphicObjects/Image.cs b/src/GraphicObjects/Image.cs index 6a4c590d..84385e85 100644 --- a/src/GraphicObjects/Image.cs +++ b/src/GraphicObjects/Image.cs @@ -79,9 +79,9 @@ namespace Crow if (string.IsNullOrEmpty(value)) Picture = null; else { - lock(CurrentInterface.LayoutMutex){ - LoadImage (value); - } + CrowMonitor.Enter(CurrentInterface.LayoutMutex, "load image"); + LoadImage (value); + CrowMonitor.Exit(CurrentInterface.LayoutMutex); } } catch (Exception ex) { Debug.WriteLine (ex.Message); diff --git a/src/GraphicObjects/MessageBox.cs b/src/GraphicObjects/MessageBox.cs index d8ce1dae..88be521e 100644 --- a/src/GraphicObjects/MessageBox.cs +++ b/src/GraphicObjects/MessageBox.cs @@ -132,18 +132,20 @@ namespace Crow close (); } public static MessageBox Show (Type msgBoxType, string message, string okMsg = "", string cancelMsg = ""){ - lock (Interface.CurrentInterface.UpdateMutex) { - MessageBox mb = new MessageBox (); - mb.Initialize (); - mb.CurrentInterface.AddWidget (mb); - mb.MsgType = msgBoxType; - mb.Message = message; - if (!string.IsNullOrEmpty(okMsg)) - mb.OkMessage = okMsg; - if (!string.IsNullOrEmpty(cancelMsg)) - mb.CancelMessage = cancelMsg; - return mb; - } + MessageBox mb = null; + CrowMonitor.Enter (Interface.CurrentInterface.UpdateMutex, "message box show"); + mb = new MessageBox (); + mb.Initialize (); + mb.CurrentInterface.AddWidget (mb); + mb.MsgType = msgBoxType; + mb.Message = message; + if (!string.IsNullOrEmpty(okMsg)) + mb.OkMessage = okMsg; + if (!string.IsNullOrEmpty(cancelMsg)) + mb.CancelMessage = cancelMsg; + CrowMonitor.Exit (Interface.CurrentInterface.UpdateMutex); + return mb; + } } } diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index eea3a184..c2184867 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -160,13 +160,15 @@ namespace Crow NotifyValueChanged ("Data", data); - lock (CurrentInterface.LayoutMutex) - ClearItems (); + CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templated group enclosing clearItems"); + ClearItems (); + CrowMonitor.Exit (CurrentInterface.LayoutMutex); if (data == null) return; loadingThread = new CrowThread (this, loading); + loadingThread.thread.Name = "list loading thread"; loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e); loadingThread.Start (); @@ -324,8 +326,9 @@ namespace Crow if (page == items) return; - lock (CurrentInterface.LayoutMutex) - items.AddChild (page); + CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templeted group add chile (page)"); + items.AddChild (page); + CrowMonitor.Exit (CurrentInterface.LayoutMutex); #if DEBUG_LOAD loadingTime.Stop (); @@ -377,12 +380,13 @@ namespace Crow iTemp = ItemTemplates ["default"]; } - lock (CurrentInterface.LayoutMutex) { - g = iTemp.CreateInstance(CurrentInterface); - page.AddChild (g); - //g.LogicalParent = this; - registerItemClick (g); - } + CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templeted group add item to page"); + g = iTemp.CreateInstance(CurrentInterface); + page.AddChild (g); + //g.LogicalParent = this; + registerItemClick (g); + CrowMonitor.Exit (CurrentInterface.LayoutMutex); + if (iTemp.Expand != null && g is Expandable) { (g as Expandable).Expand += iTemp.Expand; diff --git a/src/Interface.cs b/src/Interface.cs index df6a5c67..ffb7e312 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -124,11 +124,13 @@ namespace Crow /// Coordinate of the dirty bmp on the original bmp public Rectangle DirtyRect; /// Locked for each layouting operation - public object LayoutMutex = new object(); + public NamedMutex LayoutMutex = new NamedMutex("LAYOUTING"); /// Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...) - public object RenderMutex = new object(); + public NamedMutex DrawingQueueMutex = new NamedMutex("DRAWING QUEUE"); + /// Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...) + public NamedMutex RenderMutex = new NamedMutex("RENDERING"); /// Global lock of the update cycle - public object UpdateMutex = new object(); + public NamedMutex UpdateMutex = new NamedMutex("UPDATE"); //TODO:share resource instances /// /// Store loaded resources instances shared among controls to reduce memory footprint @@ -255,12 +257,11 @@ namespace Crow /// of this Interface public GraphicObject LoadInterface (string path) { - lock (UpdateMutex) { - GraphicObject tmp = Load (path); - AddWidget (tmp); - - return tmp; - } + CrowMonitor.Enter (UpdateMutex, "load interface"); + GraphicObject tmp = Load (path); + AddWidget (tmp); + CrowMonitor.Exit (UpdateMutex); + return tmp; } /// Create an instance of a GraphicObject linked to this interface but /// not added to the GraphicTree @@ -368,12 +369,12 @@ namespace Crow /// GraphObj's property Set methods could trigger an update from another thread public void EnqueueForRepaint(GraphicObject g) { - lock (DrawingQueue) { - if (g.IsQueueForRedraw) - return; + CrowMonitor.Enter (DrawingQueueMutex, "engueue for repaint"); + if (!g.IsQueueForRedraw){ DrawingQueue.Enqueue (g); g.IsQueueForRedraw = true; } + CrowMonitor.Exit (DrawingQueueMutex); } /// Main Update loop, executed in this interface thread, lock the UpdateMutex /// Steps: @@ -406,8 +407,9 @@ namespace Crow for (int i = 0; i < tmpThreads.Length; i++) tmpThreads [i].CheckState (); - if (!Monitor.TryEnter (UpdateMutex)) + if (!CrowMonitor.TryEnter (UpdateMutex, "main update loop")) return; + #if MEASURE_TIME updateMeasure.StartCycle(); @@ -432,7 +434,7 @@ namespace Crow updateMeasure.StopCycle(); #endif - Monitor.Exit (UpdateMutex); + CrowMonitor.Exit (UpdateMutex); } /// Layouting loop, this is the first step of the udpate and process registered /// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which @@ -442,7 +444,7 @@ namespace Crow layoutingMeasure.StartCycle(); #endif - if (Monitor.TryEnter (LayoutMutex)) { + if (CrowMonitor.TryEnter (LayoutMutex, "main layouting loop")) { DiscardQueue = new Queue (); //Debug.WriteLine ("======= Layouting queue start ======="); LayoutingQueueItem lqi; @@ -455,7 +457,7 @@ namespace Crow lqi.ProcessLayouting (); } LayoutingQueue = DiscardQueue; - Monitor.Exit (LayoutMutex); + CrowMonitor.Exit (LayoutMutex); DiscardQueue = null; } @@ -472,10 +474,12 @@ namespace Crow #endif GraphicObject g = null; while (DrawingQueue.Count > 0) { - lock (DrawingQueue) - g = DrawingQueue.Dequeue (); - lock (g) - g.ClippingRegistration (); + CrowMonitor.Enter (DrawingQueueMutex, "clipping registration"); + g = DrawingQueue.Dequeue (); + CrowMonitor.Exit (DrawingQueueMutex); + CrowMonitor.Enter (g.mutex, "after dequeue, before entering clipping registration"); + g.ClippingRegistration (); + CrowMonitor.Exit (g.mutex); } #if MEASURE_TIME @@ -510,7 +514,7 @@ namespace Crow #if DEBUG_CLIP_RECTANGLE clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5)); #endif - lock (RenderMutex) { + CrowMonitor.Enter (RenderMutex, "creating dirty rect"); // Array.Copy (bmp, dirtyBmp, bmp.Length); IsDirty = true; if (IsDirty) @@ -535,7 +539,7 @@ namespace Crow } else IsDirty = false; - } + CrowMonitor.Exit (RenderMutex); clipping.Reset (); } //surf.WriteToPng (@"/mnt/data/test.png"); @@ -565,8 +569,9 @@ namespace Crow } } - lock (UpdateMutex) - GraphicTree.Insert (ptr, g); + CrowMonitor.Enter (UpdateMutex, "interface add widget"); + GraphicTree.Insert (ptr, g); + CrowMonitor.Exit (UpdateMutex); g.RegisteredLayoutings = LayoutingType.None; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); @@ -578,11 +583,11 @@ namespace Crow if (g.Contains (_hoverWidget)) HoverWidget = null; } - lock (UpdateMutex) { - g.DataSource = null; - g.Visible = false; - GraphicTree.Remove (g); - } + CrowMonitor.Enter (UpdateMutex, "interface delete widget"); + g.DataSource = null; + g.Visible = false; + GraphicTree.Remove (g); + CrowMonitor.Exit (UpdateMutex); } /// Put widget on top of other root widgets public void PutOnTop(GraphicObject g, bool isOverlay = false) @@ -601,17 +606,20 @@ namespace Crow } if (GraphicTree.IndexOf(g) > ptr) { - lock (UpdateMutex) { + CrowMonitor.Enter (UpdateMutex, "interface put on top"); + GraphicTree.Remove (g); GraphicTree.Insert (ptr, g); - } + CrowMonitor.Exit (UpdateMutex); + EnqueueForRepaint (g); } } /// Remove all Graphic objects from top container public void ClearInterface() { - lock (UpdateMutex) { + CrowMonitor.Enter (UpdateMutex, "clear interface"); + while (GraphicTree.Count > 0) { //TODO:parent is not reset to null because object will be added //to ObjectToRedraw list, and without parent, it fails @@ -620,7 +628,8 @@ namespace Crow g.Visible = false; GraphicTree.RemoveAt (0); } - } + CrowMonitor.Exit (UpdateMutex); + #if DEBUG_LAYOUTING LQIsTries = new List(); curLQIsTries = new LQIList(); @@ -642,7 +651,8 @@ namespace Crow #endregion public void ProcessResize(Rectangle bounds){ - lock (UpdateMutex) { + CrowMonitor.Enter (UpdateMutex, "process resize"); + clientRectangle = bounds; int stride = 4 * ClientRectangle.Width; int bmpSize = Math.Abs (stride) * ClientRectangle.Height; @@ -653,7 +663,8 @@ namespace Crow g.RegisterForLayouting (LayoutingType.All); clipping.AddRectangle (clientRectangle); - } + CrowMonitor.Exit (UpdateMutex); + } #region Mouse and Keyboard Handling @@ -733,17 +744,16 @@ namespace Crow } //top level graphic obj's parsing - lock (GraphicTree) { - for (int i = 0; i < GraphicTree.Count; i++) { - GraphicObject g = GraphicTree [i]; - if (g.MouseIsIn (e.Position)) { - g.checkHoverWidget (e); - if (g is Window) - PutOnTop (g); - return true; - } + for (int i = 0; i < GraphicTree.Count; i++) { + GraphicObject g = GraphicTree [i]; + if (g.MouseIsIn (e.Position)) { + g.checkHoverWidget (e); + if (g is Window) + PutOnTop (g); + return true; } } + HoverWidget = null; return false; } diff --git a/testDrm/Main.cs b/testDrm/Main.cs index 73a165b6..0895e0c9 100644 --- a/testDrm/Main.cs +++ b/testDrm/Main.cs @@ -30,14 +30,18 @@ using System.Collections.Generic; using Cairo; using Crow.Linux; using Crow; +using System.Reflection; +using System.Linq; namespace testDrm { public class TestApp : Application, IValueChange { + [STAThread] static void Main () { + System.Threading.Thread.CurrentThread.Name = "Main"; try { using (TestApp crowApp = new TestApp ()) { crowApp.Run (); @@ -45,6 +49,7 @@ namespace testDrm } catch (Exception ex) { Console.WriteLine (ex.ToString ()); } + Console.WriteLine ("terminating"); } #region IValueChange implementation @@ -56,28 +61,107 @@ namespace testDrm } #endregion - public bool Running = true; + public TestApp () : base () { } + int frTime = 0; int frMin = int.MaxValue; int frMax = 0; + #region Test values for Binding +// public int intValue = 500; +// DirectoryInfo curDir = new DirectoryInfo (System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); +// public FileSystemInfo[] CurDirectory { +// get { return curDir.GetFileSystemInfos (); } +// } +// public int IntValue { +// get { +// return intValue; +// } +// set { +// intValue = value; +// NotifyValueChanged ("IntValue", intValue); +// } +// } +// void onSpinnerValueChange(object sender, ValueChangeEventArgs e){ +// if (e.MemberName != "Value") +// return; +// intValue = Convert.ToInt32(e.NewValue); +// } +// void change_alignment(object sender, EventArgs e){ +// RadioButton rb = sender as RadioButton; +// if (rb == null) +// return; +// NotifyValueChanged ("alignment", Enum.Parse(typeof(Alignment), rb.Caption)); +// } +// public IList List2 = new List(new string[] +// { +// "string1", +// "string2", +// "string3", +// } +// ); +// public IList TestList2 { +// set{ +// List2 = value; +// NotifyValueChanged ("TestList2", testList); +// } +// get { return List2; } +// } + IList testList = Crow.Color.ColorDic; + public IList TestList { + set{ + testList = value; + NotifyValueChanged ("TestList", testList); + } + get { return testList; } + } +// string curSources = ""; +// public string CurSources { +// get { return curSources; } +// set { +// if (value == curSources) +// return; +// curSources = value; +// NotifyValueChanged ("CurSources", curSources); +// } +// } +// bool boolVal = true; +// public bool BoolVal { +// get { return boolVal; } +// set { +// if (boolVal == value) +// return; +// boolVal = value; +// NotifyValueChanged ("BoolVal", boolVal); +// } +// } + + #endregion public override void Run () - { + { Stopwatch frame = new Stopwatch (); - Load ("#testDrm.ui.menu.crow").DataSource = this; - Load ("#testDrm.ui.0.crow").DataSource = this; - Load ("#testDrm.ui.0.crow").DataSource = this; - Load ("#testDrm.ui.0.crow").DataSource = this; - Load ("#testDrm.ui.0.crow").DataSource = this; +// Load ("#testDrm.ui.menu.crow").DataSource = this; +// Load ("#testDrm.ui.0.crow").DataSource = this; +// Load ("#testDrm.ui.0.crow").DataSource = this; +// Load ("#testDrm.ui.0.crow").DataSource = this; + //System.Threading.Thread.Sleep (100); + int i = 0; while(Running){ try { frame.Restart(); + i++; + base.Run (); +// + if (i == 1000){ + Load ("#testDrm.ui.menu.crow").DataSource = this; + } + frame.Stop(); frTime = (int)frame.ElapsedTicks; NotifyValueChanged("frameTime", frTime); @@ -99,6 +183,14 @@ namespace testDrm { Running = false; } + void onLoadClick(object send, Crow.MouseButtonEventArgs e) + { + Console.WriteLine ("********** LOADING ui item ******************"); + GraphicObject go = Load ("#testDrm.ui.2.crow"); + Console.WriteLine ("********** SETTING DATASOURCE ON ITEM ******************"); + go.DataSource = this; + Console.WriteLine ("********** LOADING FINISHED ******************"); + } } } diff --git a/testDrm/src/Application.cs b/testDrm/src/Application.cs index 43330e03..88e8116c 100644 --- a/testDrm/src/Application.cs +++ b/testDrm/src/Application.cs @@ -40,7 +40,8 @@ using OpenTK.Platform.Linux; namespace Crow { public class Application : IDisposable - { + { + public bool Running = true; DRI.GPUControler gpu; Cairo.GLSurface cairoSurf; @@ -61,9 +62,8 @@ namespace Crow // Crow.XCursor cursor; int previousVT = -1, appVT = -1; -// - public Application(){ + public Application(){ if (Kernel.signal (Signal.SIGUSR1, switch_request_handle) < 0) throw new Exception ("signal handler registation failed"); if (Kernel.signal (Signal.SIGINT, sigint_handler) < 0) @@ -83,17 +83,17 @@ namespace Crow gpu = new DRI.GPUControler(); cairoSurf = gpu.CairoSurf; - cursor = Crow.XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0]; - CrowInterface = new Interface (); Thread t = new Thread (interfaceThread); + t.Name = "Interface"; t.IsBackground = true; t.Start (); initInput (); CrowInterface.ProcessResize (new Size (gpu.Width, gpu.Height)); + cursor = Crow.XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0]; gpu.updateCursor (cursor); //CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged; } @@ -105,8 +105,8 @@ namespace Crow } } void sigint_handler (Signal s){ - Console.WriteLine ("SIGINT catched"); - //Running = false; + Console.WriteLine ("{0}: SIGINT catched", CrowMonitor.timer.ElapsedTicks); + Running = false; } // void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e) // { @@ -132,10 +132,16 @@ namespace Crow // using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) { // ctx.Rectangle (0, 0, gpu.Width, gpu.Height); -// ctx.SetSourceRGB (0, 0, 0.1); +// ctx.SetSourceRGB (0, 0, 1); +// ctx.Fill (); +// ctx.Rectangle (5, 5, 50, 50); +// ctx.SetSourceRGB (1, 0, 0); +// ctx.Fill (); +// ctx.Rectangle (1550, 850, 50, 50); +// ctx.SetSourceRGB (0, 1, 0); // ctx.Fill (); // } - if (Monitor.TryEnter (CrowInterface.RenderMutex)) { + if (CrowMonitor.TryEnter (CrowInterface.RenderMutex, "cairo paint dirty rect on backend surf")) { if (CrowInterface.IsDirty) { CrowInterface.IsDirty = false; update = true; @@ -149,9 +155,9 @@ namespace Crow } } } - Monitor.Exit (CrowInterface.RenderMutex); + CrowMonitor.Exit (CrowInterface.RenderMutex); } - +// // if (!update) // return; // update = false; @@ -160,6 +166,8 @@ namespace Crow cairoSurf.SwapBuffers (); gpu.Update (); + //Thread.Sleep (1); + //gpu.MarkFBDirty (); } @@ -212,6 +220,7 @@ namespace Crow void initInput (){ Semaphore ready = new Semaphore(0, 1); input_thread = new Thread (InputThreadLoop); + input_thread.Name = "input_thread"; input_thread.IsBackground = true; input_thread.Start(ready); } diff --git a/testDrm/src/Egl/Context.cs b/testDrm/src/Egl/Context.cs index 122f2e72..b8efecc8 100644 --- a/testDrm/src/Egl/Context.cs +++ b/testDrm/src/Egl/Context.cs @@ -290,9 +290,6 @@ namespace EGL [DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitNative")] [return: MarshalAsAttribute(UnmanagedType.I1)] public static extern bool WaitNative(int engine); - [DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapBuffers")] - [return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool SwapBuffers(EGLDisplay dpy, EGLSurface surface); [DllImportAttribute("libEGL.dll", EntryPoint = "eglCopyBuffers")] [return: MarshalAsAttribute(UnmanagedType.I1)] public static extern bool CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); diff --git a/testDrm/src/Egl/Surface.cs b/testDrm/src/Egl/Surface.cs index ccfcaa9c..5a441a56 100644 --- a/testDrm/src/Egl/Surface.cs +++ b/testDrm/src/Egl/Surface.cs @@ -41,23 +41,26 @@ namespace EGL { #region pinvoke [DllImportAttribute("libEGL.dll")] - public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list); + internal static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list); [DllImportAttribute("libEGL.dll")] - public static extern EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list); + internal static extern EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list); [DllImportAttribute("libEGL.dll")] - public static extern EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list); + internal static extern EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list); [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool eglDestroySurface(EGLDisplay dpy, EGLSurface surface); + internal static extern bool eglDestroySurface(EGLDisplay dpy, EGLSurface surface); [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value); + internal static extern bool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value); [DllImportAttribute("libEGL.dll")] - public static extern EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list); + internal static extern EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list); [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value); + internal static extern bool eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value); [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool eglBindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer); + internal static extern bool eglBindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer); [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] - public static extern bool eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer); + internal static extern bool eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer); + [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)] + internal static extern bool eglSwapBuffers(EGLDisplay dpy, EGLSurface surface); + #endregion Context ctx; @@ -75,6 +78,10 @@ namespace EGL if (!Context.MakeCurrent(ctx.dpy, handle, handle, ctx.ctx)) throw new NotSupportedException(string.Format("eglMakeCurrent on surface Failed: {0}",Context.GetError())); } + public void SwapBuffers () { + if (!eglSwapBuffers (ctx.dpy, handle)) + throw new NotSupportedException(string.Format("eglSwapBuffers Failed: {0}",Context.GetError())); + } #region IDisposable implementation ~Surface(){ diff --git a/testDrm/src/Linux/DRI.cs b/testDrm/src/Linux/DRI.cs index c1f60a41..b509697d 100644 --- a/testDrm/src/Linux/DRI.cs +++ b/testDrm/src/Linux/DRI.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Diagnostics; +using System.Threading; namespace Linux.DRI { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -124,7 +125,8 @@ namespace Linux.DRI { Resources resources = null; Connector connector = null; Crtc currentCrtc = null; - ModeInfo currentMode; + ModeInfo currentMode, originalMode; + uint originalFB; public GPUControler(string gpu_path = "/dev/dri/card0"){ fd_gpu = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec); @@ -149,6 +151,42 @@ namespace Linux.DRI { public int Width { get { return (int)currentMode.hdisplay; }} public int Height { get { return (int)currentMode.vdisplay; }} + ModeInfo getNewMode(){ + ModeInfo mode = currentCrtc.CurrentMode; + mode.clock = 118250; + mode.hdisplay = 1600; + mode.hsync_start = 1696; + mode.hsync_end = 1856; + mode.htotal = 2112; + mode.vdisplay = 900; + mode.vsync_start = 903; + mode.vsync_end = 908; + mode.vtotal = 934; + mode.flags |= (uint)VideoMode.NHSYNC; + mode.flags |= (uint)VideoMode.PVSYNC; + return mode; + } + unsafe void setNewMode(){ + + //currentCrtc.handle->mode = currentMode; +// ModeInfo* mode = (ModeInfo*)Marshal.AllocHGlobal (sizeof(ModeInfo));// pConnector->modes; +// *mode = currentMode; + + uint fb; + GBM.gbm_bo* bo = GBM.BufferObject.gbm_bo_create (gbmDev.handle, (uint)Width, (uint)Height, GBM.SurfaceFormat.ARGB8888, GBM.SurfaceFlags.Scanout); + int ret = drmModeAddFB (fd_gpu, (uint)Width, (uint)Height, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb); + if (ret != 0) + Console.WriteLine ("addFb failed: {0}", ret); + bo->SetUserData ((IntPtr)fb, handleDestroyFB); + + uint connId = connector.Id; + ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode); + if (ret != 0) + Console.WriteLine ("set new mode setCrtc failed: {0}", ret); + //GBM.BufferObject.gbm_bo_destroy (bo); + + //Console.WriteLine ("new mode set to {0} x {1}", Width, Height); + } bool defaultConfiguration (){ //select the first connected connector foreach (Connector c in resources.Connectors) { @@ -161,12 +199,17 @@ namespace Linux.DRI { return false; currentCrtc = connector.CurrentEncoder.CurrentCrtc; - currentMode = currentCrtc.CurrentMode; - + originalMode = currentCrtc.CurrentMode; + originalFB = currentCrtc.CurrentFbId; + currentMode = getNewMode(); + + //configure a rendering stack gbmSurf = new GBM.Surface (gbmDev, Width, Height, GBM.SurfaceFlags.Rendering | GBM.SurfaceFlags.Scanout); + setNewMode (); + eglSurf = new EGL.Surface (eglctx, gbmSurf); eglSurf.MakeCurrent (); @@ -179,7 +222,17 @@ namespace Linux.DRI { if (cairoDev.Acquire () != Cairo.Status.Success) Console.WriteLine ("[Cairo]: Failed to acquire egl device."); - + +// using (Cairo.Context ctx = new Cairo.Context (CairoSurf)) { +// ctx.Rectangle (0, 0, Width, Height); +// ctx.SetSourceRGB (0, 0, 1); +// ctx.Fill (); +// } +// CairoSurf.Flush (); +// CairoSurf.SwapBuffers (); +// Update (); + + //Thread.Sleep (1); return true; } void handleDestroyFB(ref GBM.gbm_bo bo, IntPtr data) @@ -200,126 +253,38 @@ namespace Linux.DRI { GBM.gbm_bo* bo; uint fb; -// PollFD fds = new PollFD(); -// fds.fd = fd_gpu; -// fds.events = PollFlags.In; -// -// EventContext evctx = new EventContext(); -// evctx.version = EventContext.Version; -// evctx.page_flip_handler = PageFlipPtr; - -// int timeout = -1;//block ? -1 : 0; -// - if (!gbmSurf.HasFreeBuffers) throw new NotSupportedException("[GBM] Out of free buffer"); bo = gbmSurf.Lock (); - //fb = getFbFromBo (bo); - //unsafe { - //Console.WriteLine ("current fb: {0}", currentCrtc.CurrentFbId); - //if (currentCrtc.CurrentFbId == 0) - int ret = drmModeAddFB (fd_gpu, currentMode.hdisplay, currentMode.vdisplay, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb); - if (ret != 0) - Console.WriteLine ("addFb failed: {0}", ret); - //else - // fb = currentCrtc.CurrentFbId; - bo->SetUserData ((IntPtr)fb, handleDestroyFB); + int ret = drmModeAddFB (fd_gpu, currentMode.hdisplay, currentMode.vdisplay, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb); + if (ret != 0) + Console.WriteLine ("addFb failed: {0}", ret); + bo->SetUserData ((IntPtr)fb, handleDestroyFB); - uint connId = connector.Id; - ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode); - if (ret != 0) - Console.WriteLine ("setCrtc failed: {0}", ret); - //} - gbmSurf.Release (bo); + uint connId = connector.Id; + ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode); + if (ret != 0) + Console.WriteLine ("setCrtc failed: {0}", ret); - //bo.Dispose (); -// -// SetScanoutRegion (fb); -// drmTimeOut.Restart(); -// -// while (run && drmTimeOut.ElapsedMilliseconds < 10000){ -// BufferObject next_bo; -// bool update = false; -// -// if (updateMousePos) { -// lock (Sync) { -// updateMousePos = false; -// unsafe { -// Drm.MoveCursor (fd_gpu, pEncoder->crtc_id, MouseX-8, MouseY-4); -// } -// } -// } -// -// if (Monitor.TryEnter (CrowInterface.RenderMutex)) { -// if (CrowInterface.IsDirty) { -// CrowInterface.IsDirty = false; -// update = true; -// using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) { -// using (Cairo.Surface d = new Cairo.ImageSurface (CrowInterface.dirtyBmp, Cairo.Format.Argb32, -// width, height, width * 4)) { -// ctx.SetSourceSurface (d, 0, 0); -// ctx.Operator = Cairo.Operator.Source; -// ctx.Paint (); -// } -// } -// } -// Monitor.Exit (CrowInterface.RenderMutex); -// } -// -// if (!update) -// continue; -// update = false; -// -// cairoSurf.Flush (); -// cairoSurf.SwapBuffers (); -// -// if (Gbm.HasFreeBuffers (gbm_surface) == 0) -// throw new Exception ("[GBM]: Out of free buffers."); -// -// next_bo = Gbm.LockFrontBuffer (gbm_surface); -// if (next_bo == BufferObject.Zero) -// throw new Exception ("[GBM]: Failed to lock front buffer."); -// -// fb = getFbFromBo (next_bo); -// -// unsafe{ -// int is_flip_queued = 1; -// -// while (Drm.ModePageFlip (fd_gpu, pEncoder->crtc_id, fb, PageFlipFlags.FlipEvent, ref is_flip_queued) < 0) { -// //Console.WriteLine ("[DRM] Failed to enqueue framebuffer flip."); -// continue; -// } -// -// while (is_flip_queued != 0) -// { -// fds.revents = 0; -// if (Libc.poll (ref fds, 1, timeout) < 0) -// break; -// -// if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0) -// break; -// -// if ((fds.revents & PollFlags.In) != 0) -// Drm.HandleEvent (fd_gpu, ref evctx); -// else -// break; -// Thread.Sleep (1); -// } -// if (is_flip_queued != 0) -// Console.WriteLine ("flip canceled"); -// -// Gbm.ReleaseBuffer (gbm_surface, bo); -// //Drm.ModeRmFB(fd_gpu, fb); -// -// bo = next_bo; -// next_bo = BufferObject.Zero; -// -// } -// } + gbmSurf.Release (bo); + } + [StructLayout(LayoutKind.Sequential)] + struct drmClip { + public ushort x1; + public ushort y1; + public ushort x2; + public ushort y2; + } + unsafe public void MarkFBDirty(){ + IntPtr pClip = Marshal.AllocHGlobal (sizeof(drmClip)); + drmClip dc = new drmClip () { x1 = 0, y1 = 0, x2 = 500, y2 = 500 }; + Marshal.StructureToPtr (dc, pClip,false); + int ret = drmModeDirtyFB (fd_gpu, currentCrtc.CurrentFbId, IntPtr.Zero, 0); + if (ret < 0) + Console.WriteLine ("set FB dirty failed: {0}", ret); } - #region cursor GBM.BufferObject boMouseCursor; @@ -359,28 +324,7 @@ namespace Linux.DRI { drmModeMoveCursor (fd_gpu, currentCrtc.Id, x, y); } #endregion -// void initGbm (){ -// gbm_surface = Gbm.CreateSurface(gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Rendering | SurfaceFlags.Scanout); -// if (gbm_surface == IntPtr.Zero) -// throw new NotSupportedException("[GBM] Failed to create GBM surface for rendering"); -// -// unsafe { -// gbm_bo* bo = Gbm.CreateBO (gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Scanout); -// if (bo == null) -// Console.WriteLine ("failed to create a BufferObject for screen 0"); -// else { -// uint fb_id = screens [0].BindBuffer (bo); -// // if (paint (bo)) -// // Console.WriteLine ("[DRI] bo paint succeed"); -// // ModeDirtyFB (fd_gpu, fb_id, IntPtr.Zero, 0); -// } -// // //Gbm.DestroyBuffer (bo); -// ModeAddFB (fd_gpu, bo->Width, bo->Height,(byte)depth, (byte)bpp, bo->Stride, bo->Handle32, out fb_id); -// bo->SetUserData ((IntPtr)fb_id, IntPtr.Zero); -// -// int ret = ModeSetCrtc(fd_gpu, crtc_id, fb_id, x, y, &connector_id, 1, ref mode); -// } -// } + // unsafe public drmPlane GetPlane (uint id) { // drmPlane p = new drmPlane(); // drmPlane* pPlane = ModeGetPlane (fd_gpu, id); @@ -418,6 +362,13 @@ namespace Linux.DRI { CairoSurf = null; } + uint connId = connector.Id; + unsafe{ + int ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, originalFB, 0, 0, &connId, 1, ref originalMode); + if (ret != 0) + Console.WriteLine ("restore Crtc failed: {0}", ret); + } + if (boMouseCursor != null) boMouseCursor.Dispose (); boMouseCursor = null; @@ -452,9 +403,8 @@ namespace Linux.DRI { byte bpp, uint stride, uint bo_handle, out uint buf_id); [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] public static extern int drmModeRmFB(int fd, int bufferId); - [DllImport(lib, EntryPoint = "drmModeDirtyFB", CallingConvention = CallingConvention.Cdecl)] - public static extern int ModeDirtyFB(int fd, uint bufferId, IntPtr clips, uint num_clips); - + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] + public static extern int drmModeDirtyFB(int fd, uint bufferId, IntPtr clips, uint num_clips); [DllImport(lib, EntryPoint = "drmModeGetFB", CallingConvention = CallingConvention.Cdecl)] unsafe internal static extern drmFrameBuffer* ModeGetFB(int fd, uint fb_id); @@ -481,6 +431,9 @@ namespace Linux.DRI { [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] unsafe static extern int drmModeSetCrtc(int fd, uint crtcId, uint bufferId, uint x, uint y, uint* connectors, int count, ref ModeInfo mode); + [DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)] + unsafe static extern int ModeSetCrtc(int fd, uint crtcId, uint bufferId, uint x, uint y, uint* connectors, int count, ModeInfo* mode); + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] internal static extern int drmModeSetCursor2(int fd, uint crtcId, uint bo_handle, uint width, uint height, int hot_x, int hot_y); diff --git a/testDrm/src/Linux/DRI/Connector.cs b/testDrm/src/Linux/DRI/Connector.cs index 97acf4b8..9021cfad 100644 --- a/testDrm/src/Linux/DRI/Connector.cs +++ b/testDrm/src/Linux/DRI/Connector.cs @@ -128,7 +128,7 @@ namespace Linux.DRI #endregion int fd_gpu; - drmConnector* handle; + internal drmConnector* handle; #region ctor public Connector (int _fd_gpu, uint _id) diff --git a/testDrm/src/Linux/DRI/Encoder.cs b/testDrm/src/Linux/DRI/Encoder.cs index a3b3b705..09376501 100644 --- a/testDrm/src/Linux/DRI/Encoder.cs +++ b/testDrm/src/Linux/DRI/Encoder.cs @@ -50,7 +50,7 @@ namespace Linux.DRI #endregion int fd_gpu; - drmEncoder* handle; + internal drmEncoder* handle; #region ctor unsafe internal Encoder (int _fd_gpu, uint _id) diff --git a/testDrm/src/Linux/GBM/BufferObject.cs b/testDrm/src/Linux/GBM/BufferObject.cs index fd6adcb8..7f6012b3 100644 --- a/testDrm/src/Linux/GBM/BufferObject.cs +++ b/testDrm/src/Linux/GBM/BufferObject.cs @@ -55,7 +55,7 @@ namespace Linux.GBM { #region pinvoke [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)] - static extern gbm_bo* gbm_bo_create (IntPtr gbm, uint width, uint height, SurfaceFormat format, SurfaceFlags flags); + internal static extern gbm_bo* gbm_bo_create (IntPtr gbm, uint width, uint height, SurfaceFormat format, SurfaceFlags flags); [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)] internal static extern void gbm_bo_destroy (gbm_bo* bo); [DllImport("gbm", CallingConvention = CallingConvention.Cdecl)] diff --git a/testDrm/testDrm.csproj b/testDrm/testDrm.csproj index 5517f274..e4864697 100644 --- a/testDrm/testDrm.csproj +++ b/testDrm/testDrm.csproj @@ -27,10 +27,10 @@ DEBUG; prompt 4 - false true $(SolutionDir)build\obj\$(Configuration) - $(SolutionDir)build\$(Configuration) + $(SolutionDir)build\Debug + true full @@ -40,7 +40,7 @@ false true $(SolutionDir)build\obj\$(Configuration) - $(SolutionDir)build\$(Configuration) + $(SolutionDir)build\Release @@ -81,6 +81,7 @@ + @@ -105,6 +106,9 @@ + + + diff --git a/testDrm/testThreadMonitor.cs b/testDrm/testThreadMonitor.cs new file mode 100644 index 00000000..264fd2cf --- /dev/null +++ b/testDrm/testThreadMonitor.cs @@ -0,0 +1,90 @@ +// +// Main.cs +// +// Author: +// Jean-Philippe Bruyère +// +// Copyright (c) 2013-2017 Jean-Philippe Bruyère +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Diagnostics; +using System.IO; +using System.Collections.Generic; +using System.Threading; + +namespace testMonitor +{ + + public class testMonitor + { + static object _obj = new object(); + static object mutex1 + { + get + { + System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1); + System.Diagnostics.Debug.WriteLine(String.Format("Lock acquired by: {0} on thread {1}", frame.GetMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId)); + return _obj; + } + } + + [STAThread] + static void Main () + { + + Thread t1 = new Thread (thread1); + t1.Start (); + Thread t2 = new Thread (thread2); + t2.Start (); + + while (true) { + continue; + Monitor.Enter (mutex1); + //Console.WriteLine ("Main thread entered mutex1 lock"); + Thread.Sleep (1000); +// Console.WriteLine ("Main Thread wait state mutex1 lock"); +// Monitor.Wait (Mutex1); +// Console.WriteLine ("Main Thread wait finished mutex1 lock"); + Monitor.Exit (mutex1); + Thread.Sleep (1); + //Console.WriteLine ("Thread 1 state: {0}", t1.ThreadState.ToString ()); + } + + + } + + static void thread1(){ + while (true) { + Monitor.Enter (mutex1); + Thread.Sleep (1000); + Monitor.Exit (mutex1); + Thread.Sleep (1); + } + } + static void thread2(){ + while (true) { + Monitor.Enter (mutex1); + Thread.Sleep (1000); + Monitor.Exit (mutex1); + Thread.Sleep (1); + } + } + } +} \ No newline at end of file diff --git a/testDrm/ui/0.crow b/testDrm/ui/0.crow index 744f3cb4..bcb80e7c 100755 --- a/testDrm/ui/0.crow +++ b/testDrm/ui/0.crow @@ -149,10 +149,9 @@ --> - + + \ No newline at end of file diff --git a/testDrm/ui/1.crow b/testDrm/ui/1.crow new file mode 100755 index 00000000..c6979205 --- /dev/null +++ b/testDrm/ui/1.crow @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/testDrm/ui/2.crow b/testDrm/ui/2.crow new file mode 100755 index 00000000..2b2ead7a --- /dev/null +++ b/testDrm/ui/2.crow @@ -0,0 +1,95 @@ + + + + +