CALayer flickering when adding a foreground layer to IKImageBrowserView items with garbage collection on - cocoa

I'm trying to implement a technique similar to the one in the ImageBrowserViewAppearance sample code from Apple (located here: http://developer.apple.com/library/mac/#samplecode/ImageBrowserViewAppearance/Introduction/Intro.html ), where CALayers are generated on top of the items in the IKImageBrowserView to customize the appearances of the objects in the image browser.
However, I'm getting a weird problem when I turn on garbage collection, and I can reproduce it in the Apple sample code. Simply turn on Garbage Collection in the target, and build and launch the ImageBrowserAppearance sample app. Then, add some photos to the image browser using the "Add Photos..." button.
Now, click on an empty portion of the IKImageBrowserView, and click and drag to start selecting multiple items in the browser view. As you drag the selection box around, you should notice that sometimes the pin and gloss overlay for some of the items flicker and briefly appear in the bottom-left corner of the IKImageBrowserView. All of the CALayers seem to do this occasionally, I've seen the white surrounding slide area flicker down into the bottom-left corner as well.
When I mimic the technique in my own code, I (not surprisingly) also can reproduce this badge flickering. However, this problem disappears when garbage collection is off.
Anybody have a clue what could be going wrong here? I'd like to use garbage collection in my app in conjunction with this technique, but the flickering is kind of annoying.

I bookmarked this a while back but Apple's changed the URL and the text. Fortunately I quoted it when I bookmarked it:
The Core Graphics APIs (Quartz 2D) see an approximately 25% reduction in drawing performance for applications compiled to use garbage collection.
That "25% reduction in drawing performance" text has been rewritten into a "slight overhead in code execution" and that was for 10.5. Perhaps Apple fixed it for 10.6. And you're talking Core Animation, not Core Graphics.
Still, Core Animation eventually has to talk to Core Graphics, and perhaps that performance issue hasn't gone away, and you're being bitten by it.

I fooled around with this a bit and can confirm I get the same behavior running the project with GC turned on. In fact, if you're patient enough and slowly change the selection one image at a time using the arrow keys, eventually it'll trigger the behavior and you can see the layers from one image in the view are displayed in the lower left corner instead of on top of the image. I haven't been able to find any sort of pattern as to when it happens, or any relation between which image is selected and which image has its layers missing. I'm assuming that for whatever reason, those layers are getting their frame origin set to {0, 0}, but heck if I know why.

Related

JavaFX DragView Image has lowered opacity compared to actual image... Can that be changed?

I have been working on using Drag and Drop with JavaFX, and one thing I notice is that items are given lowered opacity compared to their actual images, as well as the larger the image the made "Faded/transparent" the image gets. I am working on am application that can drag fairly large items which end up almost invisible when dragging, which defeats the purpose of using a DragView Image in the first place, and makes this unusable for larger items (the way I'm using the DragView I want the images to be a certain size compared to the scene in which I'm dragging onto).
My application essentially has 2 Windows (Stages) where the data is in one Stage and I get the item from a list and drag it onto the scene. The DragView image is a representation of the object going onto the scene, so when I drop the DragView Image, it gets dropped exactly into place on the scene, so the DragView is important to my overall application.
Just a NOTE: There is also backing data in my transfer in order to recreate the box, as well as additional data that gets transferred with the Drag and Drop.
I tried looking at the FX DragView Internal code but didn't find anything that sets the Opacity or anything like that, so one of my assumptions of "it's built into the OS" is something I keep thinking about, as lowered opacity is something I remember being built in, and when trying it it does happen, but very very slight, and not as bad as what I'm experiencing (Also possible that since the icons are much smaller they don't run into the "larger image opacity issue."
I am running Windows 7 64-Bit for those who are wondering.
My question is, is it possible to change the opacity settings of the Drag and Drop ImageView either via JavaFX or possibly Native with using something along the lines of JNI?
I don't have any example code at the moment, but can add if someone is interested, but I'm sure for those who know about Drag and Drop ImageViews should already know about the opacity.
Thank you all.

ScreenSpace canvas not working

I am upgrading the UI of my program (from the old Unity UI system to the new one), but it seems like I cannot work with screen-space canvas (either camera or overlay canvases). Objects in world-space canvases work fine. With screen-space GameObjects show in my "Game" preview-screen in the editor, so I am a bit confused as to what the problem may be. To be clear: objects show in the "Game" screen, but not when I press the "play" button.
I attach a composite screenshot with information about one of the objects, the canvases and the camera.
I think I now understand what the problem is. Apparently screen-space canvases (either overlay or camera) can ONLY work with UI-specific game objects. I still do not know why other sorts of elements can be added as children of these canvases (and specially why they correctly show in the Game-preview screen!)
Even if I am missing something deeper here, using elements from the UI folder works where others don't. I thought perhaps someone could find that useful.

The internals of NSScrollView

When you gently scroll an NSScrollView the rectangle that Cocoa marks as dirty, and passes to drawRect, is often trivially small (perhaps as small as one or two pixels in height, for a vertical scroll view). The framework clearly already knows what the majority of the content is (because it's on screen) and where to redraw it (just the offset brought about by the scroll), so all it needs the developer to do is fill in the small rectangle that's about to appear. I was wondering what's happening behind the scenes to allow this to happen?
For example, if I wanted to implement my own super-smooth scroll view as a learning project, what kind of data would I be recording about the document view to enable me to just re-position - rather than redraw - the majority of it. Is Cocoa constantly generating images on background threads that it draws on screen when required, or is there something a bit more subtle going on?
There's lots going on. If you haven't already read it, you should read the Scroll View Programming Guide for Cocoa.
The copying of the existing rendering is accomplished by -[NSView scrollRect:by:]. It's only done if the NSClipView that's part of the NSScrollView architecture is set to copy-on-scroll (the copiesOnScroll property).
Also, there's "responsive scrolling". Since 10.9, if certain conditions are met, AppKit will speculatively render the document view beyond the visible rect so that, when the user scrolls, it can show the scrolled-in area without asking the document view to render.
You can set your views to be layer-backed. In that case, they are typically rendered to textures and composited by the window server. This means they don't necessarily have to re-draw to render in a new position. It's quite likely that responsive scrolling uses layers behind the scenes to hold the pre-rendered content.

How to properly use setPatternOffset to fix NSColor colorWithPatternImage insanity

I'm trying to draw a tiled pattern inside a NSScrollView which is itself inside a resizable window (on Mac OS X). The code simply calls [NSColor colorWithPatternImage], CGContextSetFillColorWithColor, and CGContextFillRect.
The problem is that the pattern is drawn relative to the bottom-left corner of the window. This is documented behavior, but causes two unpleasant effects:
When the window is resized, the pattern scrolls up or down in a very surprising manner.
When the scroll view is scrolled, and then scrolled back, the newly drawn pattern doesn't line up with the scrolled (buffered) part of the pattern.
I'm able to mostly fix problem 2 by calling CGContextConvertPointToDeviceSpace, passing in 0,0, and seeing what I get back -- this tells me my scroll offset, which I can then use with CGContextSetPatternPhase to fix the problem. (Though it doesn't completely fix it -- when I scroll quickly, I still see mismatched patterns, for reasons I haven't sorted out yet.)
But addressing problem 1 is proving really thorny. From my drawing code, which only knows the CGContext, I can't find any way to get the window height. (The Device/User space conversion routines seem completely unaffected by window height.)
Short of adding a bunch of plumbing to all the drawing code to pass around a window reference, is there any way to figure out the correct offset so that my pattern will stay put when the window is resized, and scroll properly when the scrollview is scrolled?
Oops -- shortly after posting this, I found at least a partial answer: the current transformation matrix (from CGContextGetCTM) reflects both the window height, and the scroll offset.
(Or at least, it does in my app; I set the CTM very early in the pipeline to give me a top-down coordinate system so I can use much the same code on iOS.)
So, if I just call CGContextGetCTM, and then pass the .x0 and .y0 values of the result to CGContextSetPatternPhase, it mostly works.
I'm still running into some visual glitches when I scroll quickly horizontally, though not vertically -- a very odd effect, which suggests to me that it might be something in my code, or perhaps related to how wide the content area is. I'll dig further.

hiding movieclip, rendering performance

I'm developing a rendering engine for a game i am currently building..
I have a main camera (rectangle) that determines what needs to be rendered (thing within it's boundaires)
I am using a bitmap rendering method for the background and that all works fine.
but for the character i am using a movieclip over the top.
when the character goes out of the camera's view is it 100% neccesary to set visible=false?
atm the game is running at 30 FPS (as intended) and everything is sweet, i just wanted to ask out of curiosity.
Is flash clever enough to not bother with movieclip outside of the scene boundaires?
Thanks in advance,
Rory
According to http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e3e.html Flash won't render if an object is outside of Stage boundaries:
Display list
The hierarchy of display objects that will be rendered as visible
screen content by Flash Player and AIR. The Stage is the root of the
display list, and all the display objects that are attached to the
Stage or one of its children form the display list (even if the object
isn’t actually rendered, for example if it’s outside the boundaries of
the Stage).
In my experience display objects added to the stage cause a performance hit even if they are not rendered.
Setting visible to false causes a much lower performance hit, but still a small hit.
Removing unnecessary display objects from the display list is a documented performance tip from adobe as well.
Of course, if you only have a few dislay objects it might not be worth the effort, but if we talk about large amounts of display objects I strongly recommend removing them from the display list.

Resources