Moonlight 4 Preview 1 is out

by Miguel de Icaza

Yesterday we released Moonlight 4, Preview 1.

This release of Moonlight completes the Moonlight 3 feature set and includes many features from Silverlight 4. Check out our release notes for the list of things that are currently missing from our Silverlight 4 support.

Rendering

Moonlight rendering system uses a painter's algorithm coupled with culling to reduce the amount of rasterization that needs to take place.

For example, if we had these objects all rendered at the same location, on top of each other:

A simple implementation would render the triangle, then the rectangle and then the circle, and we would get this result:

Moonlight optimizes this rendering by computing the bounding boxes of each element and determining which objects are completely obscured. In this case, the triangle never needs to be rendered as it is fully covered.

Since we have the entire graph scene in memory, we can push all the rendering to the X server without ever having to pull data back from it.

Each visible element on Silverlight derives from the class UIElement and Moonlight tracks the bounding box for all of each individual element. As you compose elements, the aggregate bounding box is computed. For example, a canvas that hosts these three UIElements would have a bounding box that contains all three of them:

New Rendering Features

With Silverlight 3, Microsoft introduced two large important changes to the framework: 3D transformations on objects and support for pixel shaders. Both of these are applied to every visual element in Silverlight (this is implemented in the class UIElement).

In addition to the properties inherited from Silverlight 2, UIElements now have two new properties: Projection and Effect.

The Projection property is a 3D matrix transformation (the 3D variation of the 2D affine transform that is available in most 2D graphics APIs). Silverlight exposes both the raw 3D matrix or a set of convenient properties that are easier to use and require no understanding of the interactions of the twelve elements of the 3D matrix (see this page for an explanation).

Just like 2D affine APIs typically expose convenience methods to scale, rotate, skew and translate, the PlaneProjection properties allow developers to focus on those components.

You can see a sample here.

Effects follow a similar pattern. The blur and drop-shadow effects are given convenient names and accessors (BlurEffect and DropShadowEffect but Silverlight exposes an API to create programmable pixel shaders that go beyond these two simple cases.

The ShaderEffect allows users to load pixel shaders written using the High Level Shader Language (HLSL). Here is a sample app showing pixel shaders in action.

3D transformations and pixel shaders require that the contents of a UIElement are rendered to an intermediate output surface. The 3D transformation and shader effect is applied when this surface is composited onto the parent output surface. This compositing operation can be accelerated using graphics hardware.

From our previous example, the three elements would be rendered into a 2D surface, and the actual transformation can be done in the hardware:

Finally, the third new rendering upgrade was the introduction of a bitmap cache that can be applied to a UIElement. When a UIElement is flagged for being bitmap cached, the same kind of intermediate surface rendering and hardware accelerated compositing is performed as for elements with 3D transformations or pixel shaders. The contents of bitmap cache elements are also rendered once and kept on a bitmap that is later composited. This can improve performance vastly for complex controls with many interlocking pieces: instead of computing and re-rendering the entire contents every time, the bitmap cache is used.

This of course has some visible effect. If you instruct Silverlight to use a bitmap cache, and then you zoom-in the contents, you will see the result get pixelated. You can learn more about this on the BitmapCache documentation.

Moonlight's New Rendering Pipeline and GPU Acceleration

Both effects and projections can be implemented purely in software. Effects can be implemented by providing a small interpreter for HLSL code and projections by performing the rendering in software and compositing the results.

David Reveman, the hacker behind Compiz joined the Moonlight team last year to implement the new rendering primitives, but also to figure out how we could hardware accelerate Moonlight. The results of his work are available on yesterday's release of Moonlight 4.

The rendering pipeline was modified. Now, whenever a UIElement has either a Projection, an Effect or has the the flag BitmapCache set the entire UIElement and its children are rendered into a surface that is then off-loaded for the GPU to render.

When OpenGL is available on the system, the composition of UIElements is entirely done by the GPU.

Moonlight will use the GPU to accelerate for compositing, perspective transformations and pixel shaders if the hardware is present without having to turn this on. Silverlight by default requires developers to opt into hardware acceleration and has its own set of features that it will hardware accelerate.

In general, Moonlight uses the GPU more than Silverlight does, except in the case of DeepZoom, where we still do not accelerate this code path.

Gallium3D

Our new rendering pipeline is built using OpenGL and Gallium3D.

Gallium is an engine that is typically used to implement OpenGL. In our case, we use the Gallium3D API when we need to fallback to software rendering 3D transforms on Linux. Otherwise we go through the OpenGL pipeline:

If we were to only support Linux/X11, Gallium3D would have been a better choice for us. But we want to allow the Moonlight runtime to be ported to other windowing systems (Like Wayland on Linux) and other operating systems.

Room for Growth

Now that we have this 3D accelerated platform in place, it is easy to fine-tune specific UIElements to be hardware accelerated.

This first release did only the basics, but we can now trivially use hardware decoders for video and have that directly composited in hardware with the rest of a scene, or we can offload image transformations entirely to the hardware on a type-by-type basis and of course, DeepZoom.

Object Lifecycle

Objects in moonlight live in two spaces, low-level components live in C++ and are surfaced to C#. Typically this means that we have code that looks like this in C++:

	//
	class MyElement : public UIElement {
	  protected:
		MyElement ();
	  private:
	        // fields and methods for MyElement go here
	}
	

In C# we create a mirror, like this:


	public class DependencyObject {
		// Points to the C++ instance.
		IntPtr _native;
	}
	

When a user wrote in C# "new MyElement", we would P/Invoke into C++ code that does "new MyElement", get a pointer back to this instance and store it in the "_native" field.

In the other direction, if we created a C++ object and then we had to "surface" it to the managed world, we would initialize the object based on our C++ "this" pointer.

We could create instances of MyElement in C++, and when this instance needs to be surfaces to the managed world, we would create an instance of the managed object, and store the pointer to the underlying C++ object in the _native pointer.

In the Moonlight 2.0 days we used to have C++ objects that would only create managed objects on demand. At the time, we did this to avoid creating thousands of managed objects when loading a XAML file when only a handful of those would be controlled by user code.

The Moonlight runtime, running in pure C++ code, surfaced objects to the C# world and we tracked the object life cycle with good old reference counts. But with Silverlight 2, we started to see problems with the design as it was possible to end up with cycles. These cycles did not happen only in the C++ side or the C# side, but they spanned the boundaries. This made it very hard to debug and it made it hard to keep Moonlight from not leaking memory.

Templates for example could create these cycles.

With Moonlight 4, we have landed a new life cycle management system that works like this:

  • Every C++ object that we create always points to a managed counterpart. Gone are the days where the managed peer was created only when needed.
  • Every C++ instance field that points to a DependencyObject subclass goes through this cool C++ templated class that notifies managed when the reference changes.
  • There are no ref/unref pairs surrounding stores to instance fields in c++ anymore.

Now our base class in C++ has this:

	// Our entire hierarchy exposed to managed code
	// derives from EventObject
	class EventObject {
        	GCHandle managed_handle;
	}
	

Now all the c++ objects exist and are kept alive solely by their managed peers (there are some rare exceptions for things like async calls) and the whole graph is traversable by Mono's GC because all stores to c++ instance fields result in a managed ref between the respective peers.

With the new code, we no longer live in a world of refs/unrefs (again, except for some rare cases) and whenever we assign to a C++ field that points to a managed object we notify the managed peer of the change.

We were not able to ship Moonlight 4 with our new garbage collection system (Sgen) as we ran into a couple of hard to track down bugs at the last minute, but we are going to switch it on again soon.

Future Work

There is still room for improvement, and now that we know how to cook this kind of code, the goal is to use Mono's new GC in Moonlight more extensively.

We want to teach SGen to scan the C++ heap and track references to managed objects, dropping another potential source of problems and reducing the code needed. We would also love to go back to only creating managed objects on demand.

Platform Abstraction Layer

Moonlight was originally designed as a Linux-only, X11-only plugin for rendering Silverlight content. Developers constantly ask us whether they could run Moonlight on platform XX that is either not Linux or does not use X11.

The amount of work to port Moonlight 2 to those kinds of scenarios was so overwhelming that most people abandoned the efforts relatively quickly.

With Moonlight 4, we have introduced a new platform abstraction layer that will make it simpler for developers to port the Moonlight engine to other platforms.

Whether you want hardware accelerated user experiences in your video game or you want to put Moonlight on a the FreezeMaster 10000 Domestic Fridge with an Internet Connection and SmoothStreaming running on a barebones ARM CPU, you can now enjoy this in the comfort of your home.

We have done some minimal tests to exercise the API and can run the Moonlight engine on both MacOS and Android. You can look at exclusive footage of the animation test suite running on OSX and on Android.

If you are like me, not much of a click-on-the-video kind of person, and would rather get a screenshot, you can bask on the smooth colors of this screenshot on Android or in this delightful test on MacOS.

We are currently not planning on completing that work ourselves, so this is a fabulous opportunity for a caffeine-driven hacker to complete these ports.

Some possibilities, from the top of my head include being able to use Silverlight to design parts of your user experience for apps on the Mac AppStore (think MoonlightView in your MonoMac apps), or for your Android app.

Using Expression beats coding cute animations and futuristic UIs by hand. That is why every major video game embeds ScaleForm, the embeddable Flash runtime for handling the UI.

New XAML Parser

Our original XAML parser was written in C++, this worked fine for Moonlight 1, but with Moonlight 2 it started to become obvious that we were spending too much time calling back from C++ to C# to create managed objects.

This was acceptable up to version 2, but it no longer scaled with Moonlight 3. Too much time was spent going back and forth between the C++ world and the C# world. Those following the development of Moonlight would have noticed that every couple of weeks a new extra parameter to the xaml_load function was added to deal with yet another callback.

The new XAML parser is entirely written in C#, is faster and more reliable.

And lots more

Check out our release notes for Moonlight 4 Preview 1.

Posted on 16 Feb 2011


Three Months and Ten Days

by Miguel de Icaza

That is the time between our last major Mono release and the new hotness: Mono 2.10.

New in this release:

Check out our Mono 2.10 release notes for all the details.

Posted on 16 Feb 2011


Nokia Simplifies the Mobile Landscape

by Miguel de Icaza

On Friday, Nokia announced that they were adopting WP7 as their operating system. Although some open source advocates might see this as a set-back for Linux, Android is already the best-selling Linux OS of all times. Meanwhile, as a Ben Zander student, all I see is possibility and the the world of opportunities that this opens to developers.

Although they will continue shipping Symbian for a while, they are effectively sun-setting it. Just like you can still purchase Itanium systems from HP, nobody really develops for those anymore.

Nokia had this chart to offer on Friday:

This is fascinating turn of events for C# developers as Nokia will make WP7 more relevant in the marketplace, making C# the lingua-franca of all major mobile operating systems. This astute chart explains why I am basking in joy:

C# and the ECMA CLI everywhere!

Now, certainly lots of developer houses can afford to build their software once for each platform. This is fine if your VC has a mandate to "spend that cash quickly" or if you have a surplus of interns at your disposal.

Now, if trollcats have taught us one thing is that users like the UI of their apps to be as native as possible. That is, mind-blowingly beautiful on iOS and try to match the carpet on the others.

Other snake oil vendors will tell you that you can use the same code across all platforms and still deliver an emotional experience to your users. I agree, you can deliver the same emotion of disgust when using a cross platform toolkit.

With Mono we have taken a different approach, based on our own failures from the past. We give developers access to all of the native APIs in the platform to create the best possible user experience, and exploit every single last bit of functionality available on the platform.

We advise our users to split their user interface code from the engine, or their business logic. Developers should create a native experience for their mobile apps: one per platform. For example, consider Angry Birds on iOS and Angry Birds on Blackberry. Each version adapts to provide the best user experience available on the platform.

This is a grand time to be a mobile developer. This chart illustrates the elegant balance of native experience and code sharing available to C# developers:

Update: As much as I have enjoyed responding to the comments on this blog post, the comments are now closed. I will make an exception with anyone that wants to follow up on an existing discussion. For everyone else, if you have something to share, write it on your blog.

Posted on 14 Feb 2011


On Reflector

by Miguel de Icaza

Red Gate announced that their Reflector tool would soon become a paid-for app. A few years ago they bought the rights to Reflector from Lutz Roeder and started maintaining two editions of the product: a free version and a commercial version with extra features. Many people in the .NET community feel unhappy about that decision.

Whether Red Gate's decision is good or not for them is up to other blogs to discuss. I am grateful that over the years Reflector ran with Mono's Windows.Forms implementation and that the maintainers were careful to keep the code running with Mono.

Of course, I would always like more an open source equivalent to a proprietary tool, and while Reflector was a free download, it was never open source.

Some believe that in response to the announcement we created a competitor to Reflector. We did not.

We have had a decompiler in Mono for a few years now. First, we had a decompiler contributed to MonoDevelop by Andrea and we later replace it with the one that was developed by JB Evain:

The current decompiler in MonoDevelop actually originated not as a decompiler, but as a flow-analysis tool in 2005. It was part of db4Object's Native Queries. Native Queries were a way of getting some of the benefits of LINQ without any compiler support. It worked by reassembling the AST at runtime from a stream of IL instructions. For example, you could use the following C# code to query a database:

IList  pilots = db.Query  (delegate(Pilot pilot) {
	return pilot.Points == 100;
});
	

The Query method would decompile the code in the delegate and reconstruct the abstract syntax tree and determine that the expression to query was pilot.Points == 100.

JB Eventually expanded hi IL Manipulation library Cecil to contain a decompiler built based on the ideas of flow analysis. JB described this back in December of 2008 as part of a Hack Week followed by a hack-a-thon:

During the last Hack-Week, I started refactoring Cecil.FlowAnalysis, and since then, I’ve been working pretty seldom on it. It was last month that I decided to give it a kick, and even took a week of vacations to organize a CodeCamp with friends to give it a boost and have fun altogether

The decompiler is just one of the various tools built with Cecil and has been a standard component of MonoDevelop for a long time (it is part of MonoDevelop 2.4).

Although yesterday in response to the announcement, a WPF UI was created for the Cecil.Decompiler.dll, this is not the only effort. There is also an older Cecil Studio that uses Windows.Forms that was created a few years ago and of course, our own MonoDevelop assembly browser.

We welcome contributions to the decompiler for people interested in improving the core, regardless of their preference for a UI built on top of it:

That being said, JB has been working on a new system that goes beyond decompilation and will be demoed at QCon next month. Stay tuned for his demo.

Posted on 04 Feb 2011


Adult Principles, from JPBarlow

by Miguel de Icaza

A few days ago, John Perry Barlow twetted a series of Adult Principles, and I enjoyed reading them. When he was asked where they came from, he said:

They're from a list I assembled for myself on the eve of my 30th birthday. Many years ago.

This is the collected set from his twitter feed:

Adult Principle #1: Be patient. No matter what.

Adult Principle #2: Don’t badmouth: Assign responsibility, not blame. Say nothing of another you wouldn't say to him.

Adult Principle #3: Never assume the motives of others are, to them, less noble than yours are to you.

Adult Principle #4 Expand your sense of the possible.

Adult Principle #5 Don’t trouble yourself with matters you truly cannot change.

Adult Principle #6 Don't ask more of others than you can deliver yourself.

Adult Principle #7 Tolerate ambiguity.

Adult Principle #8 Laugh at yourself frequently.

Adult Principle #9 Concern yourself with what is right rather than who is right.

Adult Principle #10 Try not to forget that, no matter how certain, you might be wrong.

Adult Principle #11 Give up blood sports.

Adult Principle #12 Remember that your life belongs to others as well. Don't risk it frivolously.

Adult Principles #13 Never lie to anyone for any reason. (Lies of omission are sometimes exempt.)

Adult Principle #14 Learn the needs of those around you and respect them.

Adult Principle #15 Avoid the pursuit of happiness. Seek to define your mission and pursue that.

Adult Principle #16 Reduce your use of the first personal pronoun.

Adult Principle #17 Praise at least as often as you disparage.

Adult Principle #18 Admit your errors freely and quickly.

Adult Principle #19 Become less suspicious of joy.

Adult Principle #20 Understand humility.

Adult Principle #21 Remember that love forgives everything.

Adult Principle #22. Foster dignity.

Adult Principle #23. Live memorably.

Adult Principle #24. Love yourself.

Adult Principle #25. Endure.

A small detour, he also tweeted

If you want a new, improved mate, try treating the one you have better.

Posted on 21 Jan 2011


Help us test Mono 2.10

by Miguel de Icaza

Andrew has just released the packages for our first preview of Mono 2.10, we published sources and packages for SLES, OpenSUSE, RHEL, Windows and MacOS X here:

http://mono.ximian.com/monobuild/preview/download-preview

From our draft release notes, here are some of the highlights in this release:

As well as containing a pile of bug fixes.

As I mentioned last year, we are moving to a faster release schedule to get important features out for our users faster. For instance, our SGen garbage collector has been vastly improved and should perform better under load, and our ParallelFX got some real-life testing which helped us improve it significantly.

SGen Technical Discussion

Mark has been blogging the technical details about the architecture of the SGen garbage collector, you can read the documents here:

Posted on 19 Jan 2011


Your Own Sandbox

by Miguel de Icaza

Since the beginning of time, men have sought to find a way of creating a sandbox for untrusted code running on their Mono virtual machine.

Those of you familiar with Silverlight's security system, commonly referred as CoreCLR Security, have wondered "how can I get me some of dat". Today Sebastien wrote a How-to guide for those of you interested in creating your own secure sandboxes like Moonlight or Unity3D have done.

From his blog:

So what was missing was not facts but orientation. It kind of make sense, most people are not doing an open source implementation of Silverlight, we are. However we're providing a lot of cool (yes it is ;-) stuff within - stuff, like coreclr, xaml, the cecil-based linker... that can be reused in other projects. So the missing piece is an how to for people wishing to enable CoreCLR when embeding mono in their own application. It does not bring a lot of new facts but, hopefully, it will order them in a more useful way.

Posted on 13 Jan 2011


Mono at CES: More Games

by Miguel de Icaza

During today's Nvidia press conference at CES, a the Monodroid-powered DeltaEngine was shown running the SoulCraft Tech Demo:
CES Video.

Although today's demo was powered by MonoDroid the engine is a cross-platform .NET game engine, it runs on on Mono-powered systems like Linux, MacOS X, MonoTouch and MonoDroid as well as Microsoft .NET powered systems like the XBox360, Windows Phone 7 and Windows:


If you have an iPad, you can try the Zombie Party game on the AppStore, it is the first game powered by DeltaEngine. ExDream is the group behind DeltaEngine.

For information on how the demo was built check out this blog post. The engine will be open sourced this year.

Posted on 06 Jan 2011


Mono for Android

by Miguel de Icaza

Now that we feel that we have fixed all the embarrassing bugs in Mono for Android, so we have opened up our Mono for Android preview program to anyone that wants to take it out for a spin.

Mono for Android brings the full Mono VM to Android. We use a library profile that is better suited for mobile devices, so we removed features that are not necessary (like the entire System.Configuration stack, just like Silverlight does).

In addition to bringing the core ECMA VM to Android, we bound the entire set of Android Dalvik APIs to C# and in the process C#-ified them. This includes using C# properties for metadata (less XML config file messing around), exposing C# events, C# properties, strongly typed generic types where necessary, implicit conversions where needed, using the C# API style, IEnumerable where appropriate (to let you LINQ over your Dalvik, and we turn IIterable into IEnumerables for you).

On the OpenGL front, we brought the same OpenTK library that is popular among .NET developers on both Windows, Linux and iPhone, so you can share the same OpenGL logic across all platforms.

Unlike iOS where the JIT is not supported, Mono on Android supports the full JIT, so you can use Reflection.Emit and dynamic code compilation as much as you want.

This initial release only comes with templates for C#, but other .NET compilers should work, as long as they reference Mono for Android's libraries (as we removed a few methods that make no sense on mobile devices).

Support for OSX

Through the lifetime of our preview program, Mono for Android only supported Windows development using Visual Studio. Today we are also releasing support for developing Android applications on MacOS X using MonoDevelop.

Getting Started

Please check our Welcome page, it contains installation instructions, links to tutorials, mailing lists, chat rooms and more.

I strongly advise our users to join our mailing list and to check the previous discussions on the mailing list for some tasty insights.

You can also browse the API that we expose to C# developers.

Upcoming Features

We are working as fast and as hard as we can to complete Mono for Android. This includes Linux support and bringing MonoDevelop to Windows, for users that can not run Visual Studio 2010 Professional.

Giving us Feedback

Please provide your feedback on the product directly on our mailing list, as this is what the MonoDroid developers monitor. Bug reports should be filed on Novell's Bugzilla.

Posted on 04 Jan 2011


Open Source Contribution Etiquette

by Miguel de Icaza

Some developers, when faced with fixing, or adding a feature to an open source project are under the mistaken impression that the first step before any fixing takes place, or before adding a new feature takes place is to make the code "easier for them" to work on.

"Easier for them" usually is a combination of renaming methods, fields, properties, locals; Refactoring of methods, classes; Gratuitous split of code in different files, or merging of code into a single file; Reorganization by alphabetical order, or functional order, or grouping functions closer to each other, or having helper methods first, or helper methods last. Changing indentation, aligning variables, or parameters or dozen other smaller changes.

This is not how you contribute to an open source project.

When you contribute fixes or new features to an open source project you should use the existing coding style, the existing coding patterns and stick by the active maintainer's choice for his code organization.

The maintainer is in for the long-haul, and has been working on this code for longer than you have. Chances are, he will keep doing this even after you have long moved into your next project.

Sending a maintainer a patch, or a pull request that consists of your "fix" mixed with a dozen renames, refactoring changes, variable renames, method renames, file splitting, layout changing code is not really a contribution, it is home work.

The maintainer now has to look at your mess of a patch and extract the actual improvement, wasting precious time that could have gone to something else. This sometimes negates the effort of your "contribution".

If you really have an urge to refactor the code, first of all, discuss the changes with the maintainer with the rationale for the changes. If the maintainer agrees with the changes, make sure that you keep your refactoring and changes independent from code fixes, it makes reviewing the code a lot simpler.

The alternative, to keep your fork, is usually a guarantee that your effort will be wasted, and wont help other users. People have tried to do this. It is attempted every year, by hunders of developers who in tbe back of their minds are thinking "I can do better" and "I wont make the same mistakes". After 18 years doing open source I can probably think of a handful of project forks that have survived and flourished. Out of hundreds of such failures. So the odds are not good.

So respect the original coding style, and if you want to make refactoring changes, discuss this with the maintainer.

Posted on 31 Dec 2010


« Newer entries | Older entries »