| Sign In/My Account | View Cart |
| Article: |
Graphical Composition in Avalon | |
| Subject: | macos x already works like this | |
| Date: | 2004-03-14 10:23:25 | |
| From: | mweiher | |
|
Response to: macos x already works like this
|
||
|
I think it would be easier if you separated defending your article (which rightfully addresses the needs of Windows developers) from trying to refute the statement "macos x already works like this".
|
||
Showing messages 1 through 18 of 18.
0 setgray
/Times-Italic 50 selectfont
50 150 moveto (This is an example of Quartz transparency!) show
1 0 0 setrgbcolor
.5 setalpha
100 100 200 200 rectfill
1. Application that provides smooth zoom
Just modify your NSImageView a tiny little bit. Add a class BetterNSImageView with an instance variable id pdfImageRep.
To this add the following two methods:
-(void)drawRect:(NSRect)r
{
if ( pdfImageRep ) {
[pdfImageRep drawInRect:r];
} else {
[super drawRect:r];
}
}
-(void)setImage:(NSImage*)anImage
{
[anImage setDataRetained:YES];
pdfImageRep=[[[anImage representations]
lastObject] retain];
[super setImage:anImage];
}
(This code will leak the image-rep, but that's OK for us here)
The clou here is drawing the PDF directly, instead of recaching an NSImage each time around. That makes things significantly faster. I haven't put in the code that takes care of keeping the aspect ratio the same, this doesn't affect the speed and is left as an exercise for the reader.
This redraws interactively on my dual 1 GHz G4 and my 867 MHz 12" PowerBook, though it is a bit more sluggish on the PowerBook. Or, to put numbers on that, add the following trivial "benchmark" code:
-(void)doScaleBench:sender
{
int i;
NSWindow* win=[self window];
NSRect r=[win frame];
NSLog(@"start %@",[NSDate date]);
for (i=0;i<10 ;i++) {
r.size.width++;
r.size.height++;
[win setFrame:r display:YES];
}
NSLog(@"stop %@",[NSDate date]);
}
Hook that up to a menu item in Interface Builder.
On my 867MHz 12" PowerBook, that yields between 7.41 redraws/s for a complex PDF with a full page of text and 17.2 redraws a second for a simple PDF with a couple of shapes and a small amount of text. A full page of text being rescaled is very rough, because text is expensive to render and you aren't getting much use out of the text cache.
On the 1 GHz G4, we get 12.5 and 31 redraws / second, respectively. A current model G5 should be more than twice as fast, and I wonder what will be available by the time Longhorn/Avalon ships. But it's always surprised me how much faster Safari is on my 12" PowerBook than the 1.4 GHz Dell I have at work. Apart from looking incomparably better...
2. "wether mac os x has a [retained vector] mechanism like this"
*double cough* This is from the start of my first post to this thread:
"The fact is that Mac OS X already *does* work mostly like this, except for retained vectors"
To which you replied:
"But my point is that the retained vectors are crucial."
'nuff said.
3. Quartz compositor hypotheses
Just complete bollocks. Completely unrelated. Apart from being untrue, this is still bitmaps being drawn with Quartz 2D, not stuff that is turning into bitmaps as a result of the Quartz compositor, which has nothing to do with that at all.
4. OpenGL + QuickTime + Quartz
5. Diffuse worries
OK, so you had bad experiences with Windows drawing APIs that just didn't work as advertised. Yes, that is also what I heard. Especially the transition from the initial GDI to the one that supported a "Postscript-like" imaging model, with arbitrary affine transformations. I remember thinking to myself "hey, this does all I need", but then hearing that, in fact, it doesn't actually work. However, I never tried it myself, but you seem to corroborate this.
This is also where I get confused as to which Windows API is which. I remember that the original GDI did not support arbitrary (affine) transformations, or bezier-based paths. Did it support path-based clipping? The API that followed was very closely modelled after the Postscript imaging model, but that was the one that didn't really work as advertised, at least initially. Was that GDI+? I seem to be getting conflicting messages on that. You seem to say that GDI+ came with XP, but that would mean there must have been an intermediate API. Was there some renaming in the meantime?
Anyway, whatever bad experience you had with Windows APIS, the good news is: Quartz Just Works(tm), as did DPS. Your worries, as applicable as they are in the Windows world, simply do not apply here. I have lots of ideas why this is the case, but these aren't really that important. What is important is that it does just work.
[Possible reasons: well-defined drawing model, with precisely specified rendering semantics; history of implementations that have always been and continue to be device-independent stretching back more than two decades; surrounding APIs that have traditionally always worked in conjunction with a fully device-independent imaging model and count on that working correctly; developers that have worked with a device-indepndent imaging model for more than a decade etc.]
6. Concrete compositing worries
Anyway, you do give one concrete reason why there were problems with Windows, which is that windows are composed of lots of smaller windows. This isn't the case with normal Quartz windows. It is only true (to a much lesser degree) when the Quartz compositor is used to combine other media-types.
However, virtually all the concrete worries you have expressed about (sub-)pixel boundaries, arbitrary scaling and so forth already apply today in exactly the same way! So either everything is as broken as you think it will be in the future today, or it won't be broken in the future either.
[Exposé as 'proof' of compositor limitations: how many more #$%!@# lame examples are you going to come up with?! Exposé is intended to give you a rough overview over your windows, not provide precise rendering. Also, if anything it is an example of limitations of GPU-based drawing...]
7. One big Quartz 2D surface
For most windows, that is exactly what it is. The only exceptions are those that explicitly include dynamic media such as QuickTime movies and OpenGL-rendered 3D graphics
.And yes, of course it is the compositor that is placing those QuickTime streams inside Quartz windows. What else? I really understand where you're getting all this from. You seem to have a profound misunderstanding of how all this works somewhere, but I am at a bit of a loss where it is.
8. "At 300 dpi, your 128x128 pixel image is now less than half an inch across."
This makes me wonder wether you understand what device-independent graphics means at all. Probably not. The same image will be precisely the same size as it was before. It will also look (almost) exactly the same. It just won't improve as much as a vector drawing will. However, most of the time those 128 x 128 icons are drawn much smaller than 1:1, and at those sizes a higer DPI display will display those icons with much finer details than possible today.
Incidentally, that applies to all the other bitmaps in the UI, for example the traffic-light close/minimize buttons. They will render just fine even at the higher resolution, they just won't benefit much from it. That is what device-independent rendering is all about. Of course, it will be trivial for Apple to provide higher-resolution bitmaps for those higher resolution displays, or vectorized versions if that is appropriate/desirable.
9. Static vs. dynamic graphics pipelines (and retained vectors)
'"As you yourself have pointed out, both speed and quality requirements are different for dynamic and static media" Actually I don't think I did say that.'
Er, yes you did. Earlier. On bitmap-stretching used by, for example, the genie effect:
"Quartz gets away with this for high-speed animations like minimization because they're over before you have a chance to see the imperfections. But it would not stand up to close sustained scrutiny. And a crummy image would completely defeat the purpose of a high-dpi display!"
So, at high speeds, you can get a way with imperfections. At low speeds, or a static display, you can't.
So once again, for 3D and video work, you have the fast 3D and video pipelines. For mostly static displays, you have the very high quality Quartz 2D pipeline (and you can mix in the other pipelines when necessary). Quartz 2D is plenty fast for 2D non-media, non-movie work, and offers precision/quality that other APIs can't match.
Also, you still haven't explained how 2D retained vectors would improve movie playback or OpenGL based 3D work. Are we going to vectorize movies on the fly? Is OpenGL going to render to a 2D vector representation? I don't think so.
10. "retained vectors" ... "may not the only possible solution" for "High DPI"
Good, we are making progress, then. However, it turns out that wether vectors are retained or not is completely irrelevant to the High DPI "problem".
Unless you are going to make the absolutely absurd claim that QuickTime movies are going to vectorized on the fly and OpenGL will render down to 2D vectors instead of bitmaps, you are still going to have to composite at least some bitmaps together when you join up these different pipelines, at some point, wether you have a retained vector representation or not. It only happens at a different point in the pipeline that is all, but the actual issues of compositing the bitmaps together remains exactly the same.
The other issue is bitmaps shoved into the graphics pipeline at the application end. Again, this has nothing to do with wether you have the ability to retain (vector) representations inside your graphics subsystem (or on the graphics card for that matter) at all. It is *solely* a matter of the applications providing vector or bitmap data. So once again, the API makes no difference whatsoever
.
But my point is that the retained vectors are crucial.
But other than this fundamentally important feature, yes, very roughly speaking, Mac OS X more or less works this way. I say "roughly speaking" because there is still the issue that the compositor and the 2D drawing APIs are two seperate entities. (At least that's what Apple's documentation shows in all the pictures of Quartz's architecture.) In Avalon, composition and drawing are tightly linked.
To answer your points:
(1) This PDF/Postscript thing keeps coming up. I think I already said this, but just to be clear, that's entirely internal to the Quartz 2D API, and has absolutely no bearing on the Quartz Compositor which is, as far as I can tell, resolutely bitmap based.
Try taking a screen grab using the Shift-Command-3 shortcut. This produces a PDF. When I first saw that, I thought, "Aha, this must be because Quartz uses the PDF/Postscript imaging model." But look at the PDF - it contains a big bitmap. If you zoom in on it, everything pixellates. Why? Presumably it's because displaying a window involves composition, and the Quartz Compositor is *not* in fact PDF/Postscript based, it's bitmap based. So by the time you get to composition, the PDF/Poscript nature of the Quartz 2D API has been lost, and it's just so many pixels.
So while PDF files are theoretically able to scale to typesetting resolutions, the ones the come out of the Quartz compositor don't. Try to print one of these things out on a high resolution device, and voilá, you get a low quality pixellated image.
Perhaps there is some different way of getting PDFs of the display that I don't know about. If there is, please let me know. But Apple's documentation suggests that I shouldn't be surprised that these things are all pixel-based, because that's how they claim their compositor works. And unsurprisingly, the evidence backs them up.
The fact that these things pixellate doesn't bode well for the likely quality of support for high-DPI displays. And it's hardly surprising, given that the compositor offers a range of effects that are not, as far as I know, supported in PDF. (E.g., someone else mentioned non-linear transforms such as the Genie effect. Can you do that in a PDF without dropping down to bitmaps?)
By the way, I think Apple could mostly fix this in a future version if they want to. (It would require a significant change to Quartz's design, but I can't think of any fundamental reasons they couldn't do it if they really wanted. The only truly problematic thing that springs to mind is the way gradient fills require a callback function - makes it kind of hard to push that onto the pixel shaders...) I hope they do fix these issues in the future. I'm just saying how it appears to work at the moment - after all, that is the subject of the thread. But Apple need to start making moves in this direction now if they want to be ready for high DPI displays, which brings me onto the next point:
There seems to be a lack of leadership here from Apple - all of their graphical widgets appear to be bitmaps, not vector images. This means that even if the PDF-ness of Quartz 2D did manage to permeate all the way through to the composition level, what you'd see instead of one big bitmap is a PDF containing lots of individual bitmaps. This won't scale any better than one big bitmap.
Once again, I'd better point out that I'm not a Quartz expert, I'm just reporting my findings. If someone can tell me what I'm doing wrong, and show me evidence of resolution independence I'll happily admit to error. But so far, all the experiments I've tried point strongly towards the direction of purely bitmap-oriented composition. (As do all of Apple's architecture diagrams showing how the compositor relates to the other parts of Quartz.)
I have a couple of Macs, so just tell me what I should be doing to see evidence of this supposed resolution independence, and you'll make me happy. But for the meantime, I can only go on the basis of what Apple's documentation claims, and what I've seen with my own eyes.
"Your proposed mechanism of applying a compositing transform to the completed Window is unlikely to work well even in the Windows world, because it assumes that *all* drawing by *all* applications will use the retained vector API. This assumption seems unlikely unless non-retained APIs are removed, and completely hopeless once you consider legacy applications."
You are right that legacy applications are indeed a problem. The quality of display for those will be inferior to those of native Avalon applications. But for new applications, Microsoft are providing a strong and clear lead in telling everyone that vector-based UIs are the way to go. They're also providing tool support to make this easy in practice. I see no such leadership in this direction from Apple, which leads me to conclude that Apple don't regard this as important.
So I would agree that for today's Windows applications, high DPI will be less than completely satisfactory, and the same will be true for today's OS X applications. Both OSs will have to resort to the same tricks, resulting in less than ideal image quality. But for the future, Microsoft have made their strategy clear, and have made it equally clear what high DPI support will require from developers. I don't believe Apple have made their strategy for high DPI clear yet. I hope they do soon. (And I really hope they realise that the PDF/Postscript level drawing isn't the whole story - what worries me is the possibility that they don't even know they have a problem yet. Windows' GDI+ API uses a model which is almost identical, and it isn't a complete solution to the high DPI issue either, for the same reasons.)
(Of course, both Mac OS X and Windows could introduce partial solutions to these problems - they could apply bitmap scaling to those parts of the display relying on bitmaps, and high resolution versions of everything else. But this is a difficult area to get right - even when drawing with a resolution-independent API such as GDI+ or Quartz 2D, it's surprisingly easy to write code that only works properly at one resolution, and has some visual anomalies at any other resolution. That said, I think Quartz 2D will probably have fewer problems here than Win32.)
(2)
"Most modern app development on Mac OS X is done using the Cocoa frameworks, and these will handle the refresh logic, calling your redraw methods when necessary"
That would be an example of doing your own redrawing. The fact that OS X is calling your redraw methods is a clear indication that it has not retained your UI - if it were retaining the UI, why would it need to send you a message saying "Please redraw your UI?"
3. Yes, I continue to assert that the lack of vector-level retention is a key issue. I believe it is the cause of the problem mentioned above in point (1) - the pixel-based nature of the compositor's output. It's also the reason behind (2).
I'm well aware that vector retention is an old model. I considered writing a retrospective intro to the article on our industry's tendancy to revisit old solutions, but I was already over the requested length by a large factor...
The integration with the GPU is an important feature simply because it's the only way you're going to get adequate performance for anything other than static images or very simple animations. The frame rates achievable with OpenGL are far better than with Quartz 2D. And likewise on Windows, DirectX fares better than GDI+. So in both cases, the accelerated pipeline works far faster than the unaccelerated postscript-style API.
(The reason acceleration is faster, by the way, has nothing to do with how fast the drawing can be performed, by the way. It's all to do with minimizing the amount of data that needs to be sent across the bus to the GPU. The fact that the CPU may be able to render something as fast as the GPU would have is of no consolation if you now have to transfer 200K of data into the graphics subsystem, rather than a few hundred bytes.)
I understand your point that Apple may have painted themselves into a corner here by requiring precise rendering semantics that think cannot be achieved with acceleration, although I'm not sure that's still true with the latest generation of graphics cards. GPUs have moved away from the inflexible fixed pipeline architectures popular a few years ago, and now have a much more reconfigurable set of acceleration building blocks.
Microsoft made exactly the same decision with GDI+ as Apple did with Quartz 2D - these two APIs are more or less contemporaries, and both use software rendering because of the limitations of the hardware of the late 90s and early 2000s. These hardware restrictions no longer apply, so that decision looks a little outmoded now, which is why I think it's reasonable to say that accelerating the 2D pipeline is more advanced. An unaccelerated pipeline will become increasingly anachronistic.
More importantly though, software rendering becomes a performance liability. Now that these drawing operations can be accelerated, it makes little sense not to accelerate them, because it's very easy to max out the CPU and/or PCI bus (mostly the latter) with Quartz 2D, limiting use of animation. You can happily use animations for the other parts of Quartz - QuickTime, OpenGL and the compositor itself all enable animation just fine, because not much data needs to be sent to the graphics card for each change. But you just use animation in Quartz 2D except in very limited ways. (So it's OK for the highlighted button to pulse gently because that's a tiny screen area and doesn't require a very high update rate to get that effect. But anything more ambitious is likely to peg the PCI bus or CPU.)
You might argue that this is a good thing - too much animation is distracting and pointless. And poor use of animation is just that. But I regularly watch subtle but extremely effective use of animation to present information on television. But unless/until Quartz 2D gets acceleration, it's not going to have the performance to offer the quality of visualization that is commonplace on television.
(Also, remember that 'animation' effectively includes interactive stuff like the user picking something up and moving it around. The speed at which such drawing can be updated has a significant impact on the feel of the operation.)
3c. - your point is predicated on the assumption that 2D drawing with the quality offered by Quartz 2D and GDI+ can never be accelerated. As I said above, I believe this is no longer true, so I reject your conclusion on this point for that reason.
Perhaps Apple is betting the farm on the prediction that the advantage offered by current GPUs will be transient, and that they will win in the long run, because doing everything in the CPU is more flexible. And then you can just invoke Moore's law as the solution to any performance problems. Except I think that's a flawed strategy because it ignores one very important fact: the speed at which computers can move data from one piece of memory to another has not been keeping up with Moore's law. The trend for a long time now has been for memory speed to drop further and further behind the speed at which CPUs can execute instructions.
This is an aspect that worries me about Quartz 2d's current approach: it requires large bodies of data (the bitmaps generated by the Quartz 2D code on the CPU) to be shifted to an external memory system (the graphics card) any time anything changes. This is likely to be a bottleneck already, and will become a worse one as time goes one - Moore's law is the enemy of this graphics architecture, not its friend. (A different physical architecture for the display and memory systems might mitigate this, but can Apple really afford to stop using off-the-shelf GPUs and commission the design of custom graphics chips?)
3d "As I already showed above, it is not true that vector-level retention automatically makes for less work by the programmer."
I don't think you did show it, you just claimed it. You made two points. With the first, under your label '2', you missed something crucial - having the OS send your code a message saying "you must redraw now" is not the same as not having to redraw. It's pretty much the opposite in fact. And the second thing you mentioned was QuickDraw GX, which I have to admit I have no familiarity with.
Have you tried writing any code that targets Avalon? I'm guessing not from what you've written, in which case, what are you basing your claims on? It sounds like neither of us has enough common ground to agree on here - I suspect you've not used Avalon, and I've not used QuickDraw GX. All I can say is that so far, my experience with Avalon has been positive.
"you end up simultaneously maintaining *two* models"
I agree that this issue is a potential cause of trouble, but on the other hand, there are plenty of precedents for this kind of thing working just fine: there are controls today that retain information (but not the actual drawing), so this is hardly new. (Text controls and list controls being the two obvious examples. Even though the table views go through the data source object, you still need to perform work to keep the view and the source synchronized.)
The notion of maintaining seperate objects for your view and your model isn't a new one. I've written code for both this approach, and the imperative style used by Quartz 2D and GDI+, and so far, I prefer the retained model.
But programming styles are a very personal thing - you might well simply prefer the imperative style. Fortunately, Avalon lets you use that and still get most of the performance benefit of retention: the OS will retain any drawing you give it either declaratively or imperatively and not ask you to repaint until you send it a messages saying "this piece of the UI tree is out of date, I'd like to replace it with something else." In this style of programming, you still have a repaint method just like you do in Quartz, meaning that you're no longer obliged to sync up your model with the OS's (in both cases you just say "Junk what I gave you before - I want to redraw from scratch"). It's just that you only get the repaint requests when you tell the OS that something has changed. (So it actually feels more like the relationship between the NSTableView and its data source in Cocoa.) So you can have the same programming model that OS X and GDI+ use today if you really want it without paying too much of a performance hit. (There is some perf cost - rebuilding part of the UI tree is likely to be more expensive than adjusting it. But it's still better than having to recreate it every time the OS decides it needs to refresh the display!)
"Hmm....I just profiled TextEdit during live resize, and actual drawing was a negligible percentage of total CPU usage. So what are we gaining here? [...] That isn't just premature optimziation, that is completely superluous optimization."
What kind of Mac do you have? On my 1GHz G4 PowerBook, and also on my 866Mhz iMac, resizing of windows is pretty sluggish. It seems to do resizing at a much slower rate than, say, scrolling - it behaves as though the resize rate has actually been throttled back. It's certainly not resizing at an update rate that would be fast enough on either of my Macs to do smooth transitions. (It's noticably much less smooth than scrolling, dock animations and the like.) So is that actually a realistic way of measuring performance? You're measuring something which (on both my Macs at least) is visibly obviously not going fast enough.
(Of course it could be that resizing is a difficult operation for the Quartz Extreme engine - because Quartz uses a bitmap-based composition model, it will have to rejuggle all of its composition buffers when things change sizes. So it's possible that in this particular scenario, the CPU load is low because everything is stalled waiting for the compositor; you may simply have pegged the GPU rather than the CPU. Remember that a maxed out composition engine won't max out the CPU on Quartz Extreme because with QE, composition is done by the graphics card. That's obviously speculation of course - I've no idea why resizing is so much slower than everything else in Quartz, but I'm definitely not the only person to have noticed the problem if the web is anything to go by.)