]> O.S.I.I.S - jp/crow.git/commitdiff
CrowMonitor tread logger testDrmDebugTreading
authorjpbruyere <jp.bruyere@hotmail.com>
Fri, 19 May 2017 19:33:37 +0000 (21:33 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Fri, 19 May 2017 19:33:37 +0000 (21:33 +0200)
23 files changed:
Crow.csproj
src/CrowMonitor.cs [new file with mode: 0644]
src/CrowThread.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Image.cs
src/GraphicObjects/MessageBox.cs
src/GraphicObjects/TemplatedGroup.cs
src/Interface.cs
testDrm/Main.cs
testDrm/src/Application.cs
testDrm/src/Egl/Context.cs
testDrm/src/Egl/Surface.cs
testDrm/src/Linux/DRI.cs
testDrm/src/Linux/DRI/Connector.cs
testDrm/src/Linux/DRI/Encoder.cs
testDrm/src/Linux/GBM/BufferObject.cs
testDrm/testDrm.csproj
testDrm/testThreadMonitor.cs [new file with mode: 0644]
testDrm/ui/0.crow
testDrm/ui/1.crow [new file with mode: 0755]
testDrm/ui/2.crow [new file with mode: 0755]
testDrm/ui/colorItem.crow [new file with mode: 0755]
testDrm/ui/menu.crow

index 3e8bcd553743293bc3f6f2fbb87b67a1d16be7a1..9d48069c0ef64813bee905cc4446c2d7db57b488 100644 (file)
     <Compile Include="src\Mono.Cairo\EGLDevice.cs" />
     <Compile Include="src\Mono.Cairo\DRMDevice.cs" />
     <Compile Include="src\Mono.Cairo\DRMSurface.cs" />
+    <Compile Include="src\CrowMonitor.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
diff --git a/src/CrowMonitor.cs b/src/CrowMonitor.cs
new file mode 100644 (file)
index 0000000..53b2007
--- /dev/null
@@ -0,0 +1,61 @@
+//
+// CrowMonitor.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// 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);
+               }
+       }
+}
+
index ece87fa80e46f8f99ed4ab709045c82f6f80df20..1f0b1d769e2d37f09b8c4bea10f85d2e6d7df0fa 100644 (file)
@@ -33,7 +33,7 @@ namespace Crow
        /// Thread monitored by current interface with Finished event when state==Stopped
        /// </summary>
        public class CrowThread {
-               Thread thread;
+               internal Thread thread;
                public event EventHandler Finished;
                public GraphicObject Host;
                public CrowThread (GraphicObject host, ThreadStart start){
index 5de94f6092c44702042b3a2a01618d83676a77f4..559719a923330f024e4c6796262c9585cd5e8099 100644 (file)
@@ -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);
                }
 
                /// <summary> trigger dependant sizing component update </summary>
@@ -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;
index 6a4c590d0b274ed27b17c3343e2e68fd8a7538c2..84385e850538e383f37d232cc0a9b02fe9623437 100644 (file)
@@ -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);
index d8ce1dae7d401b327d0a3ad08f9157ece9a4e722..88be521e5fdd131ad496b8655f56ab58021111da 100644 (file)
@@ -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;
+
                }
        }
 }
index eea3a18477393d31ae20eb6fbb36b3054bb65d61..c218486768c9c4d9ff07558df27535163df5ab31 100644 (file)
@@ -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;
index df6a5c670d9068611db73be316e56c980d24094b..ffb7e3129b92a677dc47b3e16b4edd4eba000b04 100644 (file)
@@ -124,11 +124,13 @@ namespace Crow
                /// <summary>Coordinate of the dirty bmp on the original bmp</summary>
                public Rectangle DirtyRect;
                /// <summary>Locked for each layouting operation</summary>
-               public object LayoutMutex = new object();
+               public NamedMutex LayoutMutex = new NamedMutex("LAYOUTING");
                /// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
-               public object RenderMutex = new object();
+               public NamedMutex DrawingQueueMutex = new NamedMutex("DRAWING QUEUE");
+               /// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
+               public NamedMutex RenderMutex = new NamedMutex("RENDERING");
                /// <summary>Global lock of the update cycle</summary>
-               public object UpdateMutex = new object();
+               public NamedMutex UpdateMutex = new NamedMutex("UPDATE");
                //TODO:share resource instances
                /// <summary>
                /// Store loaded resources instances shared among controls to reduce memory footprint
@@ -255,12 +257,11 @@ namespace Crow
                /// of this Interface</summary>
                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;
                }
                /// <summary>Create an instance of a GraphicObject linked to this interface but
                /// not added to the GraphicTree</summary>
@@ -368,12 +369,12 @@ namespace Crow
                /// GraphObj's property Set methods could trigger an update from another thread</summary>
                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);
                }
                /// <summary>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);
                }
                /// <summary>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<LayoutingQueueItem> ();
                                //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);
                }
                /// <summary> Put widget on top of other root widgets</summary>
                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);
                        }
                }
                /// <summary> Remove all Graphic objects from top container </summary>
                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<LQIList>();
                        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;
                }
index 73a165b600a50b649a69f501d3d3c44cfc8cbb0a..0895e0c9be32828c301f1524966a754565f2a235 100644 (file)
@@ -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<String> List2 = new List<string>(new string[]
+//                     {
+//                             "string1",
+//                             "string2",
+//                             "string3",
+//                     }
+//             );
+//             public IList<String> TestList2 {
+//                     set{
+//                             List2 = value;
+//                             NotifyValueChanged ("TestList2", testList);
+//                     }
+//                     get { return List2; }
+//             }
+               IList<Crow.Color> testList = Crow.Color.ColorDic;
+               public IList<Crow.Color> 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 ******************");
+               }
        }
 }
 
index 43330e03dc3af997e5dc0599a308b004019dafed..88e8116c87e3cdeaa010682a9444495396a971b7 100644 (file)
@@ -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);
                }
index 122f2e72c7d8ba7c9d5d1c6e3a1ede1b46445357..b8efecc800a677014e53654aba7821c1165a1f0a 100644 (file)
@@ -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);
index ccfcaa9ce4e2978f50024d8259bb29f791d80ac2..5a441a561b2a078d68bcd9b1d184c3bd5db747c3 100644 (file)
@@ -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(){
index c1f60a41accb04cb4e739e270808e62b9323a997..b509697dd89a9c792ac1937dc9f63cdea88bf4a0 100644 (file)
@@ -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);
 
index 97acf4b85584c011ee5d0dd36219f96d7e8b5687..9021cfadabd5ab79b9b861d7c1b86c6d5049d801 100644 (file)
@@ -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)
index a3b3b705eb618386c08c341c3259aec89bea3e96..0937650130dfff77c5b185484b7e5c3099d87898 100644 (file)
@@ -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)
index fd6adcb82c841175eb9e9b071ee269608c8b0f90..7f6012b341d431869149365b9cbc01ec7b2c7882 100644 (file)
@@ -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)]
index 5517f27475aeaa99cf562afd6567272277483075..e4864697fe75051f98b20e1fbac9d8146e93c4af 100644 (file)
     <DefineConstants>DEBUG;</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <ConsolePause>false</ConsolePause>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
-    <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+    <OutputPath>$(SolutionDir)build\Debug</OutputPath>
+    <Externalconsole>true</Externalconsole>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>full</DebugType>
@@ -40,7 +40,7 @@
     <ConsolePause>false</ConsolePause>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
-    <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+    <OutputPath>$(SolutionDir)build\Release</OutputPath>
   </PropertyGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
@@ -81,6 +81,7 @@
     <Compile Include="src\Linux\GBM\Device.cs" />
     <Compile Include="src\Application.cs" />
     <Compile Include="Main.cs" />
+    <Compile Include="testThreadMonitor.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
   <ItemGroup>
     <EmbeddedResource Include="ui\menu.crow" />
     <EmbeddedResource Include="ui\0.crow" />
+    <EmbeddedResource Include="ui\1.crow" />
+    <EmbeddedResource Include="ui\2.crow" />
+    <EmbeddedResource Include="ui\colorItem.crow" />
   </ItemGroup>
   <ItemGroup>
     <None Include="src\DRMContext.cs" />
diff --git a/testDrm/testThreadMonitor.cs b/testDrm/testThreadMonitor.cs
new file mode 100644 (file)
index 0000000..264fd2c
--- /dev/null
@@ -0,0 +1,90 @@
+//
+// Main.cs
+//
+// Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// 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
index 744f3cb4a6e7f0914c51e7088b09d18b9702c6ee..bcb80e7c336f2895c4b610e9fc70e8c8a4ca74da 100755 (executable)
                                <DirectoryView Name="dv" CurrentDirectory="/" Margin="1"/>
                        </Border>
                        <Splitter/>-->
-                       <ListBox Name="colorList" Data="{TestList}" Margin="5"
-                                        ItemTemplate="#Tests.Interfaces.colorItem.crow"
-                                        Template="#Crow.Templates.ScrollingListBox.goml"
-                                        />
+<!--                   <ListBox Name="colorList" Data="{TestList}" Margin="5"/>-->
+<!--                                    ItemTemplate="#testDrm.ui.colorItem.crow"
+                                        Template="#Crow.Templates.ScrollingListBox.goml"-->
                </VerticalStack>
        </HorizontalStack>
 </Window>
\ No newline at end of file
diff --git a/testDrm/ui/1.crow b/testDrm/ui/1.crow
new file mode 100755 (executable)
index 0000000..c697920
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<GraphicObject Width="100" Height="100" Background="Teal"/>
\ No newline at end of file
diff --git a/testDrm/ui/2.crow b/testDrm/ui/2.crow
new file mode 100755 (executable)
index 0000000..2b2ead7
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<Window Caption="Showcase" Height="90%" Width="90%">
+       <HorizontalStack >
+               <VerticalStack Width="30%" Margin="5">
+                       <Label Width="Stretched" Margin="3" Background="Onyx"/>
+                       <TextBox Text="TextBox" Multiline="true" Margin="3"/>
+                       <HorizontalStack Height="Fit" Margin="5" Background="Onyx" CornerRadius="10">
+                               <VerticalStack Spacing="5" Width="50%">
+                                       <CheckBox Fit="true" Caption="test"/>
+                                       <CheckBox Fit="true"/>
+                                       <CheckBox Fit="true"/>
+                                       <CheckBox Fit="true" IsChecked="true"/>
+                               </VerticalStack>
+                               <VerticalStack Spacing="5" Width="50%">
+                                       <RadioButton Fit="true"/>
+                                       <RadioButton Fit="true" IsChecked="true"/>
+                                       <RadioButton Fit="true"/>
+                                       <RadioButton Fit="true"/>
+                               </VerticalStack>
+                       </HorizontalStack>
+                       <HorizontalStack Height="Fit" Margin="5">
+                               <Label Text="MouseEvents" Width="50%" Margin="3"
+                                       Background="Onyx"
+                                       Foreground="DimGray"
+                                       TextAlignment="Center"
+                                       MouseEnter="{Foreground=White}"
+                                       MouseLeave="{Foreground=DimGray}"
+                                       MouseDown="{Background=DarkRed}"
+                                       MouseUp="{Background=Onyx}"/>
+                               <Label Text="MouseEvents" Width="50%" Margin="3"
+                                       Background="Onyx"
+                                       Foreground="DimGray"
+                                       TextAlignment="Center"
+                                       MouseEnter="{Foreground=White}"
+                                       MouseLeave="{Foreground=DimGray}"
+                                       MouseDown="{Background=Mantis}"
+                                       MouseUp="{Background=Onyx}"/>
+                       </HorizontalStack>
+                       <GroupBox Caption="Templated controls" Height="Fit" Margin="5">
+                               <HorizontalStack Height="Fit">
+                                       <VerticalStack Width="50%">
+                                               <CheckBox IsChecked="true" Style="CheckBox2"/>
+                                               <CheckBox Style="CheckBox2"/>
+                                               <CheckBox Style="CheckBox2"/>
+                                               <CheckBox Style="CheckBox2"/>
+                                       </VerticalStack>
+                                       <Splitter/>
+                                       <VerticalStack Width="50%">
+                                               <RadioButton Style="RadioButton2"/>
+                                               <RadioButton Style="RadioButton2"/>
+                                               <RadioButton Style="RadioButton2"/>
+                                               <RadioButton Style="RadioButton2"/>
+                                       </VerticalStack>
+                               </HorizontalStack>
+                       </GroupBox>
+                       <HorizontalStack Height="Fit">
+                               <Label Text="Spinner"/>
+                               <Spinner Fit="true"/>
+                       </HorizontalStack>
+                       <HorizontalStack Height="Fit">
+                               <Button Caption="Button"/>
+                               <Button Caption="Button" IsEnabled="false"/>
+                       </HorizontalStack>
+               </VerticalStack>
+               <Splitter/>
+               <VerticalStack Width="40%" Margin="5" Spacing="5">
+                       <Expandable Background="DimGray">
+                               <Image Path="#Crow.Images.Icons.crow.svg"/>
+                       </Expandable>
+                       <Popper Background="DimGray" >
+                               <Border Fit="True" Background="DimGray" CornerRadius="0" BorderWidth="1">
+                                       <Image Path="#Crow.Images.Icons.crow.svg" Width="100" Height="100" Margin="10"
+                                               MouseEnter="{Background=LightGray}"
+                                               MouseLeave="{Background=Transparent}"/>
+                               </Border>
+                       </Popper>
+                       <Slider Height="10" Width="90%"/>
+                       <Container Height="Fit" Width="200" Background="Onyx" Margin="2" CornerRadius="5">
+                               <ProgressBar Background="DimGray" Height="10" Value="50"/>
+                       </Container>
+                       <Image Path="#Crow.Images.Icons.crow.svg" Width="60" Height="60" Background="LightGray" />
+                       <MessageBox Movable="false"/>
+                       <ColorPicker SelectedColor="{²../go.Background}" Name="colorPicker" Background="Onyx" Margin="5" Fit="True" />
+                       <GraphicObject Name="go" Width="100" Height="60" Background="{../../colorList.SelectedItem}"/>
+                       <Label Text="{../../colorPicker.SelectedRawColor}"/>
+               </VerticalStack>
+               <Splitter/>
+               <VerticalStack Width="30%" Margin="5">
+                       <ListBox Name="colorList" Data="{TestList}" Margin="5"
+                                        ItemTemplate="#testDrm.ui.colorItem.crow"
+                                        Template="#Crow.Templates.ScrollingListBox.goml"
+                                        />
+               </VerticalStack>
+       </HorizontalStack>
+</Window>
\ No newline at end of file
diff --git a/testDrm/ui/colorItem.crow b/testDrm/ui/colorItem.crow
new file mode 100755 (executable)
index 0000000..e3e5482
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<Border Foreground="Transparent" Focusable="true" HorizontalAlignment="Left" Height="Fit" Width="200">
+       <HorizontalStack Margin="0"
+                               MouseEnter="{Background=hgradient|0:DarkRed|1:Transparent}"
+                               MouseLeave="{Background=Transparent}">
+               <GraphicObject Height="12" Width="20" Background="{}" Margin="0" CornerRadius="3"/>
+               <Label Text="{}" Margin="0" Width="Stretched"/>
+       </HorizontalStack>
+</Border>
+
index 67e5d604d8bcdfbfaeba4452e9b151ce6d6fb826..b3863d5dc829b0a6dea90f8c9ebd0aaf3399495d 100755 (executable)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <Menu>
        <MenuItem Caption="File" Width="Fit">
-               <MenuItem Caption="New" />
+               <MenuItem Caption="New"  MouseClick="onLoadClick"/>
                <MenuItem Caption="Open"/>
                <MenuItem Caption="Save"/>
                <MenuItem Caption="Quit" MouseClick="onQuitClick"/>