I am writting a tool similar to AI selection tool.
User clicks and drags a path, I use the annotator to draw the shape of the path new path to be, user releases the mouse, I stop the annotator and update the path to its new shape.
So, I open AI, start dragging an anchor of a path, I see the annotator draws then clear then draw etc.so you can see it flickers on and off very fast.
So, I switch to a different application, then switch back to AI and start again, thereafer it works, no more flickering.
Why switching back to AI makes it work? I hope I don't have to ask user to switch back to AI for it to work, that would be silly!
Has anybody experience the same thing? Is there a solution?
It seems like your annotations may be drawing/erasing themselves too often. Are you ever forcing a redraw or just drawing the annotations when you get the kCallerAIAnnotation message?
The only painting issue I've really had with annotations is that sometimes they won't update at the right time (for example, every so often when the user clicks on the plug-in tool, the annotation won't draw until the user moves the mouse over the view). For the most part, all my annotation problems were fixed by invaliding the annotation rectangle.
Have you ever notice that even AI selection tool some time does not display the little square annotation over the anchor, when you mouse over the anchor.
And that happens quite alot. I just invalidate the whole screen and draw whenever I receive kCallerAIAnnotation.
If I don't invalidate before drawing I would see trails of what I drew. Anyway, once I switch over to another application like Firefox and back to AI,
everything is OK, that is the odd thing. Another thing I notice is invalidating annotation when you recieve the tool's mouse down it does not clear the screen!
I still think AI annotation is flaky, not just for AI selection tool but for other tools that came with AI.
I hope other people does not feel this way.
I agree. The annotations need some work as they don't work correctly all the time.
I invalidate the annotation rectangle in several different places, and together it seems fairly consistent with the other AI tools. It's invalidated when the tool is selected and deselected and at the end of ToolMouseDown and ToolMouseUp. When I draw my annotation I keep track of its bounds and use those bounds for the InvalAnnotationsRect call.
I've had little trouble getting annotators to do what I want but I find that the redraw problems mostly only show up when you start using opacities. As long as I'm working with 100% alpha, you don't see any flicker. I've managed to get even that down to mostly good using a variety of tricks, but I'm still punished if I have alpha if you cause a scroll with the tool (ie. bump up against the side). Then the flicker becomes crazy; my tricks don't work on the slew of rects I get from AI after that.
This won't help when the tool starts scrolling the view, but it seemed to help when I checked the incoming annotation message to see if there were any invalidation rects. Specifically, I ignored any where numInvalidationRects was zero. Unfortunately, when you trigger a scroll it gives you extraneous messages that I couldn't figure out how to filter, but I didn't find that to be an issue so long as I had no opacity (or at least, it wasn't very noticeable).
Anyway my tool kSelectorAIInvalAnnotation got called only when other AI selection tools is mouse down.
Why don't I get a called when my tool is being used?
I am confused as to what kSelectorAIInvalAnnotation notification is for.
I thought it is there to notify you when and where you need to redraw your annotation because AI has invalidated some of the regions.
What use is kSelectorAIInvalAnnotation notification for my tool?
I think at the moment I just always redraw my annotation so long as numInvalidationRects is non-zero. Easier & faster than figuring out if its in an invalidation rect, particularly since AI ignores anything outside that box anyways.
When I say ignore when the rects is zero, I mean in response to kSelectorAIDrawAnnotation. For kSelectorAIInvalAnnotation I just iterate the list and call InvalAnnotationRect() on each (after converting to view coordinates of course). I'm not sure if I have to or not, that's some old code. Maybe its not needed. At any rate, I don't do anything else.
About the flickering of annotator, I am possitive this is due to AI annotator draw and clearing engines synchronization issue, the two processes, or threads or whatever you call them, are not synchronized. This explains the flickering, because one thread is drawing and the other thread is clearing it. The closer the two threads step on each other, the less visible your annotation appears, until they are out of sync far enough, then you will see it, but still you never know when the sync problem occurs again. The guy who wrote these engines must not know about multi-threaded issues. I am mad!!!!!!!!!!!
The annotation flickering has nothing to do with threads. It's because it sends multiple draw requests when it should be sending one. So you end up drawing, it clears that and then you draw again. If you're doing something that's requiring additional drawing, you get this repeatedly. The trouble is you can't just ignore the first draw because you might not get two draws, in which case you're screwed. There's a bunch of developers who've had this discussion in a beta program and we're still hoping that the AI team either explains to us how to detect when we really should draw, or that they fix it in the next version of Illustrator.
Out of curiosity, do you know if it's possible to draw annotations with partial transparency? The AIAnnotatorDrawer color functions only take an RGB color, but is there another way to set the color?
What you are describing is another issue I have not seen.
The issue I am seeing is, as user drag an object, in the draw callback routine, I invalidate (clear) then draw.
The sychronization issue here is the clearing engine execute after the drawing engine, hence the flickering.
Hold on. You're clearing, then drawing in the same method? Like this (pseudo-code to follow):
You're supposed to clearn a rect then wait for a kSelectorAIDrawAnnotation message from AI before drawing. If you're drawing outside of a kSelectorAIDrawAnnotation that might be why you're seeing odd behaviour. It should look more like:
No, I don't draw outside kSelectorAIDrawAnnotation.
Inside kSelectorAIDrawAnnotation, I clear then draw.
I tried clearing inside of tool drag, but with the same result.
No one should draw outside of kSelectorAIDrawAnnotation, since you don't have the drawer handle to draw.
Ok, I was just checking You're right, you shouldn't be able to draw outside of that message, but sometimes people manage strange things!
That said, you shouldn't be clearing inside a draw. You're supposed to be just drawing, not clearing. I'd go back to clearing on drag and try ignoring any draw messages that don't contain invalidation rects. The combination might fix your flicker.
Your suggestion does not fix the flickering, like I said earlier, flickering goes away after you switch focus to a different application and back to AI, thereafter no flickering. I still think the problem is thread synchronization, I wish SDK developer would confirm this.
Another thing, the draw procedure is triggered by AI whenever it wants, not by a plugin request. The draw is called when user drag and not when user mouse down. This is crazy, that means I can draw on mouse down!!!
Anyway, the whole annotation architecture need to be redone (by Adobe ofcourse).
I just want to get my final comment in and give this thread a rest.
No doubt in my mind the issue is with thread synchronization between the clearing and the drawing threads.
I hope someone from Adobe would be kind enough to admit this problem, so we don't implement tricks and patches
that would only mask the problem in some operating environments and not others. Synchronization issue need to be
fixed inside AI core, not try to mask it in the plugin, because it does not guarantee to mask the problem for all users.
Another thing is to give the plugin the ability to request a draw and a clear, and do not generate a draw automatically based on some
fixed conditions. The plugin knows when it wants to draw and when to clear. The drawing and clearing engines only need to synchonize
themselves and execute the plugin requests in the order recieved.
I thought I give it a rest, but this morning I see the same behavior in AI direct selection tool.
You may experience the same. Please try this:
Open AI, with direct selection tool, place it over an anchor of a path, you supposed to see a little square over it, but you don't.
Now, switch to a different application like Firefox, then switch back to AI, place the tool over the anchor again, now you see the little square.
That little square is an annotation and behave just like my annotation. AI annotation really need fixing!
My annotations were flicker-free until this morning, when I added some additional filled rectangles with text on them. That's when the flickering became really noticeable. Checking AIAnnotatorMessage->numInvalidationRect for values > 0 fixed the problem completely. I didn't realize the kCallerAIAnnotation message was being called as much as it was (with values == 0), and my annotations were being drawn each time unnecessarily.