Archive for 'rant'

Crunchtime!

A few weeks ago it was all calm in the source control. Now it’s crunchtime!

I’m the master of svn deception. I do tons of useless commits just so that the stats look good. Yeah!

…ok, back to work.

The awesome support we do

Yesterday’s experience catching up with Unity forums, as I remember it:

Take a quick look at zillions of new posts.

Answer about five questions with “what’s the value of your camera’s near plane?”.

There should be some way to automate all of this. For every 20th question, reply with “increase your near plane!”, or something.

Implicit to-pointer operators must die!

For the sake of the nation,
this operator must die!

Seriously. Suppose there is some class, let’s say ColorRGBAf. That has four floats inside. Now, someone at some point decided to add this operator to it:

operator float* () { /**/ }
operator const float* () const { /**/ }

Probably because it’s easier to pass color to OpenGL this way, or something like that.

This is evil. Like, really evil. Especially if that class did not have comparison operators defined, and some totally unrelated code four years later does:

if (color != oldColor) { /* … */ }

Ouch! Sounds like someone will spend four hours debugging something that looks like an event routing issue that only happens on Windows and only with optimizations on (yes, I just did that…).

What happens here? The compiler takes pointers to two colors and compares the pointers. If for some reason both colors are temporary objects, then it can even happen that both get folded into the same variable/register/whatnot. The pointers are the same. Ouch!

Implicit “nice” operators are just disguised evil. Remove that operator, add something like GetPointer() to class if someone really wants to use that, and better even make the comparison operators private and without implementations. Yes. Much better.

OpenGL 3: a big step in no direction at all?

Well, the post title pretty much summarizes my take on it, doesn’t it? I guess I could just stop typing now… but I won’t!

So after some promises, delays and a period of deadly silence, OpenGL 3.0 was released.

Response to it was “interesting“, to say at least. Some part of that response is related to seriously mishandled communication on Khronos part. Some part is because GL 3.0 is not what it was promised to be. Let’s just ignore the communication issue, it does not affect OpenGL itself in a direct way (it affects the developer community though).

By the way, I borrowed part of the post title from a blog post linked from opengl.org. In general, I do not agree with that blog post, but it’s a valid point of view. Unlike some other blog posts linked from opengl.org that are just pure garbage…

I am not sure what are the goals of OpenGL at this point. OpenGL’s current position, as far as games are concerned, seems to be roughly this:

Be the graphics API on various platforms where no alternatives are available.

Why? Because Windows has got D3D, which is far more stable, comes with useful tools, more often updated and actually works for variety of users (I’ll get to this point in a second). Mobile platforms have OpenGL ES, which is decent. All consoles have their own APIs (some of them similar to D3D, none of them similar to GL). So that leaves OpenGL as the choice on OS X, Linux and such. Not because it’s better. Because it’s the only choice.

“Oh, but look, id uses OpenGL! Two other games use OpenGL as well!” Well, good for them. But they are in a different league than “the rest of us”. For some games, driver writers will do whatever it takes to get those games running correct & fast. Surprise surprise, id games fall into this category. For the rest of us – no such luxury. Hey, try talking to your friendly IHV, the most likely answer is “yeah, but are really busy with some high profile games right now, ping us back in two months”. After two months, repeat.

So the rest comes from somone who is not working on the high-profile games that IHVs specially tune drivers to.

If OpenGL’s goals are to stay in this current position, then GL 3.0 is okay. It adds some new features, brings some extensions into core, hey, it even says “it’s quite likely that maybe perhaps someday some of the old cruft in the API will be removed, if we feel like it”. No problem with that.

However, OpenGL is advertised as something different, as if it wants to:

Be the graphics API on various platforms.

Which is quite different from it’s current position. I’m not sure if that’s the goal of OpenGL. Myself, I don’t care about the mythical cross-platform API that would actually work on those different platforms. API is a tool to do stuff; if different platforms have different APIs – no problem with that.

However, if OpenGL wants to achieve this advertised goal, it has to do several things. First and foremost:

Actually work

Stable drivers and runtime. In it’s current state, GL is too complex to implement good quality drivers/runtime. Complexity can be reduced in several ways:

  • Cleanup the API. This was what GL 3.0 was supposed to be. Actual 3.0 did not do any of that, instead it just postponed the cleanup “until we feel like it”.
  • Share some of the hard work. Why does everyone and their dog have to write GLSL preprocessor, lexer, parser and basic optimizer themselves? Define precompiled shader format, write frontend once, make it open. This would also be actually useful to reduce load times.

GL 3.0 could have done both of the above, instead it did none. It could have cleaned up the API, and provide one platform independent GL 1.x/2.x library that calls into actual 3.0 runtime. All the fixed function, immediate mode, display lists, whatever would be in one nice library. Even existing apps could continue to function transparently this way (with the benefit of actually simpler = more stable drivers).

Support platforms/hardware/features user needs

This is of course dependent on the user in question. For someone like us, we still have to support 10 year old hardware.

D3D9 does a fine job for that (provided you have drivers installed, and DX9 runtime installed – which comes included in XP SP2 and upwards). OpenGL 2.1 and earlier would do a fine job for that, provided it would “actually work” (see above).

If GL 3.0 would be as was originally promised – almost new API, shader model 2.0+ hardware, it would be sort of fine. In our case, that would mean writing and supporting two renderers – “old GL” and “new GL”, where old one would be used on old hardware or old platforms where “new GL” is not available. If the new runtime were much leaner, much more stable and generally nicer, this would not be a big problem.

With actual GL 3.0, in theory one does not have to write two renderers. Minimum hardware level for GL 3.0 is shader model 4+ though. So to support both old hardware/platforms and new hardware/platforms, quite a lot of duplication has to be done. Especially if you intend to go towards proposed “future GL path”, i.e. start dropping deprecated functionality from the codebase. At which point you’ll probably write two separate renderers already. So we’re back to where original GL 3.0 would have been, just without any extra niceness/stability/leanness right now.

Oh, and look at vendor announcements from 2008 OpenGL BOF. NVIDIA: we have almost full drivers now. AMD: we’re committed to having drivers. Intel: look for GL 3.0 on future platforms. In other words, looks like current Intel’s cards won’t ever have GL 3.0 drivers. And in our target market, Intel has the majority of cards.

That sounds very much like “just ignore whole GL 3.0 thing” plan to me.

Be nice

This is a point of far lesser importance than “actually work” and “support what is needed” ones. Having good tools (PIX, …), documentation, code examples etc. is nice. But not much more; being nicest API in the world does not do much if it does not actually work or does not support what you need. Even in this area, actual GL 3.0 is not nice – it’s full of redundancies and crap that goes 15 years back in history.

Summing it up

To me, GL 3.0 looks like a blunder. Instead of fixing the core problems, they just postponed that. Well, Keep up the good work!

Invincible shutdown buttons!

I booted into Vista yesterday to test something. It offered a bunch of updates to install. After they were installed, I got this:

Invincible buttons

I am not sure what shutdown buttons do when they look like this. I guess they are invincible, or something. Ha, I’m your log off button! You can’t kill me!

Yes, one of the updates installed was the ATI driver update, so I guess there’s some glitch somewhere in the driver update that makes some buttons be displayed like this… But hey, this is not some random driver that I found on the net, it’s the one that is officially suggested by Vista’s update!

The problem with Vista

Jeff Atwood notes the lack of polish in Windows Vista UI. Long Zheng has started Windows UI Taskforce. I agree – Vista’s UI has tons of polish problems.

You know, little things that would seem unimportant, but screams something like “I was made in a hurry by people who don’t really love me”. Aliased shield icon overlays? Check. Horrible screen flickering when logging in or UAC prompt pops up? Check. The infamous Shut Down menu? Check. Awful file copy progress dialogs? Check. Explorer window title bar sometimes displaying green progress bar inside of it for some reason I can never understand? Check. General lack of unified style for UI? Check. The list goes on.

But still, I wonder whether lack of polish is the real problem with Vista. From my point of view, lack of direction or lack of vision seems to be a problem of similar size, if not larger. What is the vision for Vista?

“Security!” is not a vision. However hard it is to make something secure, “more security” is an improvement in one area, and not a vision on what a product should be. And second, “security” does not explain everything else about Vista. At start, it looked like some architecture astronauts had some fancy visions, like “all your filesystem is a database now!”… Well, that did not end up in Vista, and it is something that users genuinely don’t care about.

I might sound like an Apple fanboy (and indeed, OS X grows on you after a while), but when upgrading from OS X 10.4 (Tiger) to 10.5 (Leopard) I had a pretty clear list of what will be more useful to me:

  • New version feels faster (on the same machine). I am not sure if it is actually faster; or it’s only a perceived improvement. Maybe they optimized something, maybe they multithreaded something, I don’t really care. It feels faster and smoother. That’s good.
  • Quick Look is amazing. A seemingly simple feature – press Space over a file to preview it. With added polish, like when pressing space over multiple images selected, you can go into slideshow mode. Simple, yet highly effective.
  • Spotlight (desktop search) that is fast.
  • …and so on.

Those are things I, as a user, care about. I want computer to feel faster. I want to instantly preview files. I want to search for something fast.

A filesystem that is a database? I can almost see the regular user salivating over that… Yeah right. Users don’t want a platform, users want useful features.

And this is where Vista fails – it does not have obvious new useful features or improvements. Aside from Direct3D 10 – which I am not using yet – all so called “improvements” just feel like gimmicks.

  • It feels slower (I don’t care whether it actually is faster but just feels sluggish). And yes, it feels slower on a quad-core CPU with 4 gigs of RAM and a fast graphics card, so no “Vista runs circles around XP on a new box” please.
  • The reorganized menus, title bars and layout of Explorer just scream “I totally don’t understand what users need” at you. Previews are too small to be useable, organization of menus and buttons is horrible, and the constantly fading-in-and-fading-out user interface elements (folders tree view) are just distracting. I dig the new Office 2007 UI and I can see some understanding of users and vision behind it (see Jensen Harris), but Vista’s UI feels like it was designed by a bunch of people who never talked to each other. And it’s not just lack of polish, the “design” of it is wrong.
  • The Sidebar? Again, an attempt at doing something that seemed good, but without any understanding. Yes, I know that Apple might have taken the idea and implemented it right, but that does not leave Sidebar as being useful.
  • The new skin? Oh come on. How many users did upgrade because window close buttons now glow in red when you hover over them?
  • Was there anything else new in Vista? I didn’t notice anything.

So this pretty much sums up my view on Vista. Zero new useful things, many annoyances. Microsoft, here’s you chance to execute it better next time around.

Argh MFC!

When introductory documentation for something has this, you know it won’t be pretty:

CAsyncMonikerFile is derived from CMonikerFile, which in turn is derived from COleStreamFile. A COleStreamFile object represents a stream of data; a CMonikerFile object uses an IMoniker to obtain the data, and a CAsyncMonikerFile object does so asynchronously.

So yeah, I am dealing with downloading something from the internet inside an ActiveX control that is written in MFC. A seemingly simple task – I give you an URL, you give me back the bytes. But no! That would not be a proper architecture, so instead it has asynchronous monikers which are based on monikers which are based on stream files which use some interfaces and whatnot. And for ActiveX controls the docs suggest using CDataPathProperty or CCachedDataPathProperty, which are abstractions build on top of the above crap. And I don’t even know what “a moniker” is!

Of course all this complexity fails spectacularly in some quite common situations. For example, try downloading something when the web server serves gzip compressed html output. Good luck trying to figure out why everything seemingly works, you are notified of downloading progress, but never get the actual downloaded bytes.

Turns out the solution is to change downloading behaviour of the above pile of abstractions to use “pull data” model, instead of default “push data” model. The default behaviour just seems to be broken (though it is not broken in that pile of abstractions, instead it is broken somewhere deeper in Windows code). Is this mentioned anywhere in the docs? Of course not!

This is pretty much how a code comment looks like for this:

We don’t use CCachedDataPathProperty because it’s awfully slow, doing data reallocations for each 1KB received. For 8MB file it’s 8000 reallocations and 32 GB (!) of data copied for no good reason!

While we’re at it, we don’t use CDataPathProperty either, because it’s a useless wrapper over CAsyncMonikerFile.

Oh, and we don’t use CAsyncMonikerFile either, because it has bugs in VS2003′ MFC where it never notifies the container that it is done with download, making IE still display “X items remaining” indefinitely. Some smart coder was converting information message and returning “out of memory” error if result was NULL, even if input message was NULL (which it often was). So we use our own “fixed” version of CAsyncMonikerFile instead.

Oh MFC, how we love thee.

On job titles and design patterns

I just changed my job title to say “Code Chef“. I like it, and it represents my current understanding of programming pretty well. I cook code. That’s my job.

Some N years ago I would have liked a title with “Architect” or “Analyst” or something like that. I would have called myself “developer” instead of “programmer” because hey, a developer thinks up things, whereas a programmer is a mere “code monkey”. More on code monkeys below.

But wait! Back then I also believed that knowing and using Design Patterns is essential for a programmer! In one place when I was interviewing new hires, design pattern knowledge was something I would look for… how stupid! Nowadays my view of patterns is more along the lines of “yeah, whatever”. I don’t exactly think of them as things from hell, but they could have caused more harm than good already.

Back to job titles. Code monkey is actually the key employee. A software product is largely defined by the code, heck, it is code. Sure, it also has the user interface, the fancy icons, the documentation, the website, the support, the roadmap and whatnot, but the code is the product, whereas everything else is more or less addons (possibly excluding UI… UI also defines the product).

Code design? Design patterns? Who cares about that.

It’s the final result that matters. Futurist programming for the win.

On the other hand, Memento Observer is probably very cool.

My experience with Crysis so far

So I decided to check out Crysis myself. A demo for a non-gamer like me would be perfect, I thought.

It’s probably three frames per second. In the menu!

I did not see the game itself yet, got bored while waiting for the after-menu-but-before-game intro movie to end (it’s not skippable, and it also ran at about three FPS). This is after watching half a dozen obligatory before-menu intro movies at 3 FPS with stuttering sound (“nvidia,vidia,vidia,vidia… the way it’s meant,meant,meant,meant…” – TWIMTBP).

All of this on a half-decent PC, I think – Intel Core 2 Quad, 4GB RAM, Radeon 3850, Windows XP, latest drivers, none of extra stuff running; the PC is able to run other 3D stuff just fine. I’m sure the developers and EA’s testing labs have tested everything extensively, but sometimes something completely random apparently can make things be oh so slow. Oh well. Get back to work.

Holy FPU precision, Batman!

(cross-posted from blogs.unity3d.com)

One of our customers found an interesting bug the other day: embedding Unity Web Player into a web page makes some javascript animation libraries not work correctly. For example, script.aculo.us or Dojo Toolkit would stop doing some of their tasks. But only on Windows, and only on some browsers (Firefox and Safari).

Wait a moment… Unity plugin makes nice wobbling web page elements not wobble anymore!? Sounds like an interesting issue…

So I prepared for a debug session and tried the usual “divide by two until you locate the problem” approach.

  • Unity Web Player is composed of two parts: a small browser plugin, and the actual “engine” (let’s call it “runtime”). First I change the plugin so that it only loads the data, but never loads or starts the runtime. Everything works. So the problem is not in the plugin. Good.
  • Load the runtime and do basic initialization (create child window, load Mono, …), but never actually start playing the content – everything works.
  • Load the runtime and fully initialize everything, but never actually start playing the content – the bug appears! By now I know that the problem is somewhere in the initialization.

Initialization reads some settings from the data file, creates some “manager objects” for the runtime, initializes graphics device, loads first game “level” and then the game can play.

What of the above could cause something inside browser’s JavaScript engine stop working? And do that only on Windows, and only on some browsers? My first guess was the most platform-specific part: intialization of the graphics device, which on Windows usually happens to be Direct3D.

So I continued:

  • Try using OpenGL instead of Direct3D – everything works. By now it’s confirmed that initializing Direct3D causes something else in the browser not work.
  • “A-ha!” moment: tell Direct3D to not change floating point precision (via a create flag). Voilà, everything works!

I don’t know how I actually came up with the idea of testing floating point precision flag. Maybe I remembered some related problems we had a while ago, where Direct3D would cause timing calculations be “off”, if the user’s machine was not rebooted for a couple of weeks or more. That time around we properly changed our timing code to use 64 bit integers, but left Direct3D precision setting intact.

Side note: Intel x86 floating point unit (FPU) can operate in various precision modes, usually 32, 64 or 80 bit. By default Direct3D 9 sets FPU precision to 32 bit (i.e. single precision). Telling D3D to not change FPU settings could lower performance somewhat, but in my tests it did not have any noticeable impact.

So there it was. A debugging session, one line of change in the code, and fancy javascript webpage animations work on Windows in Firefox and Safari. This is coming out in Unity 2.0.2 update soon.

The moral? Something in one place can affect seemingly completely unrelated things in another place!