Re: Concurrent loading of images ?

2020-05-18 Thread Gabriel Zachmann via Cocoa-dev
> I’m not sure if you can create and manipulate a CALayer on a background 
> thread, all UI code must be run on main thread.  

Yes, that's what I was suspecting, too.

Interestingly, when I create a layer in the background, and add it to the main 
layer *in the background thread* , it helps a lot.
The stuttering is much much better now! not 100% perfect, but OK to distribute, 
IMHO.
Code is attached, just for reference, should someone else stumble in here.


> 
> It’s worth noting that I’m using Lanczos scaling with cpu renderer because 
> I’m scaling relatively low-resolution images for print output so I need the 
> highest quality scaling regardless of performance.

Do you scale up? or down?

(I'm only scaling down, if any.)

> According to this NSHipster guide (https://nshipster.com/image-resizing/) 
> simply getting an appropriate size via CGImageSourceCreateThumbnailAtIndex 
> should be your best option. You’re already doing this, so maybe you don’t 
> need CIImage at all?

Yes, I have just removed CIImage functions completely.

> 
> The CALayer animation should be using the GPU.

Yes, I think, it does. 

> If loading the new image at the same time you’re starting the animation of 
> the current image causes a stutter, you could try delaying execution of your 
> block by a little (using dispatch_after instead of dispatch_async).

Good idea !
I tried that and it seems to help a bit further against stuttering.


So, thanks a million to you (and everyone else who chimed in)!
You kept me experimenting.

Best regards, Gabriel



Encl.:

This is my solution to the stuttering problem, at the moment.
(Let's hope, Apple doesn't change the semantics of all the API's, LOL.)


NSDictionary * imageOpts = @{ 
(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,  // takes 
care of EXIF orientation, too
  
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
  
(id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
  (id)kCGImageSourceShouldCacheImmediately: 
(id)kCFBooleanTrue,
  (id)kCGImageSourceThumbnailMaxPixelSize: 
@(8192)};
CGImageRef newImageRef = CGImageSourceCreateThumbnailAtIndex( new_image, 0,
   (__bridge 
CFDictionaryRef) imageOpts );

if ( prefetchLayer_ )
[prefetchLayer_ removeFromSuperlayer];
prefetchLayer_ = [CALayer layer];
prefetchLayer_.contents  = (__bridge id)(newImageRef); 
prefetchLayer_.delegate= nil;
prefetchLayer_.minificationFilter  = kCAFilterTrilinear;  
// kCAFilterLinear is faster
prefetchLayer_.magnificationFilter = imgLayer.minificationFilter;

prefetchLayer_.bounds = NSRectToCGRect( drawRect_ );

prefetchLayer_.zPosition = -10.0;
prefetchLayer_.opacity = 0.0;  // hopefully, Apple never optimizes layers 
away b/c of zero opacity!
[mainLayer_ addSublayer: prefetchLayer_];




smime.p7s
Description: S/MIME cryptographic signature
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-18 Thread Gabriel Zachmann via Cocoa-dev
Thanks a lot for your response!

I have tried the CILanczosScaleTransform filter for downsizing. I have computed 
the scale factor exactly such that the new image has an extent not larger than 
the view.
(Below is my code)
But the performance was worse, at least with the software renderer.
With the hardware renderer (kCIContextUseSoftwareRenderer: @NO), performance 
was as before, but visual artifacts were still much worse than without any 
downsizing.

If you are curious: here is a video showing the performance 

  https://owncloud.informatik.uni-bremen.de/index.php/s/wJRkK8Ek2HTp32a

(The video was made with the software renderer.)


So, right now, I am using this code:

NSDictionary * imageOpts = @{ 
(id)kCGImageSourceCreateThumbnailWithTransform: (id)kCFBooleanTrue,  // takes 
care of EXIF orientation, too
  
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent: (id)kCFBooleanTrue,
  
(id)kCGImageSourceCreateThumbnailFromImageAlways: (id)kCFBooleanTrue,
  (id)kCGImageSourceShouldCacheImmediately: 
(id)kCFBooleanTrue,
  (id)kCGImageSourceThumbnailMaxPixelSize: 
@(8192)   };
CGImageRef newImageRef = CGImageSourceCreateThumbnailAtIndex( new_image, 0, 
  
   (__bridge 
CFDictionaryRef) imageOpts );

There is still a bit of stuttering.


Maybe, it would help to create the CALayer for the new images in the background 
thread and add it to the layer hierarchy, but I haven't explored this option 
yet.
Maybe it would not help, because, maybe, at that point some process in the 
foreground would kick in again, over which I would not have control.


Best regards, Gabriel



Encl.:
Just for your reference, this is my code for downsizing using the Lanczos 
filter:

CIContext * ciContext = [CIContext contextWithOptions: 
@{kCIContextUseSoftwareRenderer: @NO} ];   // TODO: als inst.var. 
machen!
// TODO: evtl im context kCIContextPriorityRequestLow und 
useSoftwareRenderer=FALSE angeben?
CIFilter * resizeFilter = [CIFilter filterWithName: 
@"CILanczosScaleTransform" ];
[resizeFilter setValue: orientedimage forKey: kCIInputImageKey];
[resizeFilter setValue: @(scale) forKey: kCIInputScaleKey ];
[resizeFilter setValue: @(aspect) forKey:kCIInputAspectRatioKey ];
CIImage * resizedImage = resizeFilter.outputImage;
CGImageRef newImageRef = [ciContext createCGImage: resizedImage fromRect: 
resizedImage.extent]; 


> 
> Since this stutter does not occur when cycling back through images that have 
> already been assigned to the layer, it’s possible that if the size of the 
> CGImageRef does not match the size of the CALayer, there may be some kind of 
> render occuring, especially if the image is being scaled to fit the layer.  
> Do images much larger than the CALayer stutter more? 
> 
> Also, if you’re resizing, you’ll want to use CIImage’s 
> CILanczosScaleTransform filter. Simply scaling a using a transform will give 
> you a much blurrier image.
> 
> Jim Crate
> 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-14 Thread James Crate via Cocoa-dev
On May 14, 2020, at 11:13 AM, Gabriel Zachmann via Cocoa-dev 
 wrote:
> 
> I thought i'm doing that with this code:
> 
> -animateOneframe:
> // essentially, this gets called when the next image is to be displayed
> current_image_ = prefetched_image_;   // these are CGImageRef's
> dispatch_async( prefetch_queue_, ^{
>   [self loadNextImage];// stores next image in 
> prefetched_image_
> } );
> create a new CALayer, 
> assign the current_image_ as content, 
> create an animation for the layer,
> add the layer to the layer hierarchy

Since this stutter does not occur when cycling back through images that have 
already been assigned to the layer, it’s possible that if the size of the 
CGImageRef does not match the size of the CALayer, there may be some kind of 
render occuring, especially if the image is being scaled to fit the layer.  Do 
images much larger than the CALayer stutter more? 

Also, if you’re resizing, you’ll want to use CIImage’s CILanczosScaleTransform 
filter. Simply scaling a using a transform will give you a much blurrier image.

Jim Crate

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-14 Thread Gabriel Zachmann via Cocoa-dev
> 
> Ahh, there’s a jitter when moving.

Right. Sometimes it's a really lengthy stutter.

> 
> Try creating an async dispatch to a background thread in a block.

I thought i'm doing that with this code:

-animateOneframe:
 // essentially, this gets called when the next image is to be displayed
 current_image_ = prefetched_image_;// these are CGImageRef's
 dispatch_async( prefetch_queue_, ^{
   [self loadNextImage];// stores next image in 
prefetched_image_
 } );
 create a new CALayer, 
 assign the current_image_ as content, 
 create an animation for the layer,
 add the layer to the layer hierarchy

Am I not?


Best regards, Gabriel

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-13 Thread Alex Zavatone via Cocoa-dev
One cheap option would be to ease the sliding in to a stop position and have a 
nice little pause where you swap images.  Of course, that’s cheating.



> On May 13, 2020, at 3:34 PM, Gabriel Zachmann  wrote:
> 
>> 
>> Care to post a video on a Google drive so that we can see it?
> 
> Good idea - here is the video:
> 
>  https://owncloud.informatik.uni-bremen.de/index.php/s/TTGG6bKCMFLqY4g
> 
> (encoded in H265/HEVC for saving file size)
> 
> I think, you can see clearly the stuttering. Sometimes it is more subtle, 
> sometimes, the stuttering pauses the animation for a second.
> Sometimes, it occurs when the background thread is prefetching the next image 
> (usually happens directly after the switch to a new image), sometimes, it 
> happens when the new image is beginning to show (i.e., when it's CALayer is 
> added to the layer hierarchy).
> 
> I made another experiment, which puzzles me even more.
> I am storing a history of the CGImageRef's that had been displayed so far.
> When I go back through that history, I use those stored CGImageRef's to 
> create new CALayers which I then add to the layer hierarchy (the image that 
> had been shown until then is just removed from the layer hierarchy, or rather 
> its CALayer).
> The funny thing is that when I do that (using older CGImageRef's) the switch 
> from one image to the next one is instantaneous and there is no stuttering at 
> all.
> 
> You can see that in the video starting at 1:19.
> 
> It seems as if some more processing is going on when a CGImage is assigned to 
> a CALayer,
> which CGImageSourceCreateThumbnailAtIndex() and all the other functions I 
> listed below do not do.
> Or it happens at the point when an animation is added.
> And the result of that is stored inside the CGImage!
> But how can I force that in the background thread?
> (without making the animation of the foreground thread stutter.)
> 
> I made another little experiment.
> I keep (kinetically) scrolling through the source code in Xcode with high 
> velocity while my app is running in the foreground.
> And when it switches images there is sometimes even a stuttering in that 
> scrolling.
> 
>> 
>> One of my tricks (not just mine) is to have a 3 slots of for images, not 
>> just 2.  When a new image loads, take the foreground one that is blended in 
>> to 100%, put an identical one ahead of it.  Make the changes to the new and 
>> old images behind it, then hide that foreground image.
> 
> Sorry, I didn't get how that would work with my animations.
> Maybe, you can describe it again once you've seen the video.
> 
> 
> 
> Best, Gab.
> 
> 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-13 Thread Alex Zavatone via Cocoa-dev
Ahh, there’s a jitter when moving.

Try creating an async dispatch to a background thread in a block.



> On May 13, 2020, at 3:34 PM, Gabriel Zachmann  wrote:
> 
>> 
>> Care to post a video on a Google drive so that we can see it?
> 
> Good idea - here is the video:
> 
>  https://owncloud.informatik.uni-bremen.de/index.php/s/TTGG6bKCMFLqY4g
> 
> (encoded in H265/HEVC for saving file size)
> 
> I think, you can see clearly the stuttering. Sometimes it is more subtle, 
> sometimes, the stuttering pauses the animation for a second.
> Sometimes, it occurs when the background thread is prefetching the next image 
> (usually happens directly after the switch to a new image), sometimes, it 
> happens when the new image is beginning to show (i.e., when it's CALayer is 
> added to the layer hierarchy).
> 
> I made another experiment, which puzzles me even more.
> I am storing a history of the CGImageRef's that had been displayed so far.
> When I go back through that history, I use those stored CGImageRef's to 
> create new CALayers which I then add to the layer hierarchy (the image that 
> had been shown until then is just removed from the layer hierarchy, or rather 
> its CALayer).
> The funny thing is that when I do that (using older CGImageRef's) the switch 
> from one image to the next one is instantaneous and there is no stuttering at 
> all.
> 
> You can see that in the video starting at 1:19.
> 
> It seems as if some more processing is going on when a CGImage is assigned to 
> a CALayer,
> which CGImageSourceCreateThumbnailAtIndex() and all the other functions I 
> listed below do not do.
> Or it happens at the point when an animation is added.
> And the result of that is stored inside the CGImage!
> But how can I force that in the background thread?
> (without making the animation of the foreground thread stutter.)
> 
> I made another little experiment.
> I keep (kinetically) scrolling through the source code in Xcode with high 
> velocity while my app is running in the foreground.
> And when it switches images there is sometimes even a stuttering in that 
> scrolling.
> 
>> 
>> One of my tricks (not just mine) is to have a 3 slots of for images, not 
>> just 2.  When a new image loads, take the foreground one that is blended in 
>> to 100%, put an identical one ahead of it.  Make the changes to the new and 
>> old images behind it, then hide that foreground image.
> 
> Sorry, I didn't get how that would work with my animations.
> Maybe, you can describe it again once you've seen the video.
> 
> 
> 
> Best, Gab.
> 
> 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-13 Thread Gabriel Zachmann via Cocoa-dev
> 
> Care to post a video on a Google drive so that we can see it?

Good idea - here is the video:

  https://owncloud.informatik.uni-bremen.de/index.php/s/TTGG6bKCMFLqY4g

(encoded in H265/HEVC for saving file size)

I think, you can see clearly the stuttering. Sometimes it is more subtle, 
sometimes, the stuttering pauses the animation for a second.
Sometimes, it occurs when the background thread is prefetching the next image 
(usually happens directly after the switch to a new image), sometimes, it 
happens when the new image is beginning to show (i.e., when it's CALayer is 
added to the layer hierarchy).

I made another experiment, which puzzles me even more.
I am storing a history of the CGImageRef's that had been displayed so far.
When I go back through that history, I use those stored CGImageRef's to create 
new CALayers which I then add to the layer hierarchy (the image that had been 
shown until then is just removed from the layer hierarchy, or rather its 
CALayer).
The funny thing is that when I do that (using older CGImageRef's) the switch 
from one image to the next one is instantaneous and there is no stuttering at 
all.

You can see that in the video starting at 1:19.

It seems as if some more processing is going on when a CGImage is assigned to a 
CALayer,
which CGImageSourceCreateThumbnailAtIndex() and all the other functions I 
listed below do not do.
Or it happens at the point when an animation is added.
And the result of that is stored inside the CGImage!
But how can I force that in the background thread?
(without making the animation of the foreground thread stutter.)

I made another little experiment.
I keep (kinetically) scrolling through the source code in Xcode with high 
velocity while my app is running in the foreground.
And when it switches images there is sometimes even a stuttering in that 
scrolling.

> 
> One of my tricks (not just mine) is to have a 3 slots of for images, not just 
> 2.  When a new image loads, take the foreground one that is blended in to 
> 100%, put an identical one ahead of it.  Make the changes to the new and old 
> images behind it, then hide that foreground image.

Sorry, I didn't get how that would work with my animations.
Maybe, you can describe it again once you've seen the video.



Best, Gab.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-13 Thread Gabriel Zachmann via Cocoa-dev
> 
> Actually, can’t you disable screen updating while you’re swapping images?

Would that mean that the animations are not .. animating during that time?
That would defeat the whole purpose of the exercise .

If I am mistaken: how would I disable screen updates?

Best regards, Gabriel


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-12 Thread Alex Zavatone via Cocoa-dev
Actually, can’t you disable screen updating while you’re swapping images?

> On May 12, 2020, at 3:35 PM, Alex Zavatone via Cocoa-dev 
>  wrote:
> 
> Care to post a video on a Google drive so that we can see it?
> 
> One of my tricks (not just mine) is to have a 3 slots of for images, not just 
> 2.  When a new image loads, take the foreground one that is blended in to 
> 100%, put an identical one ahead of it.  Make the changes to the new and old 
> images behind it, then hide that foreground image.
> 
> You’re actually using a copy of the foreground image as a mask and you 
> perform the swap behind it, then update the screen, then remove the top level 
> one and refresh again. 
> 
> This is if I’m understanding what you’re going properly.
> 
> I’d expect that Apple’s video system to actually handle this if it still 
> triple buffers, but it’s been 25 years since I read the docs on the Mac’s 
> video subsystem.
> 
> 
> In the mean time, add logging code that you can put breatpoints on and take a 
> screen grab when you log.  That should help.
> 
> Cheers,
> Alex Zavatone
> 
>> On May 12, 2020, at 3:27 PM, Gabriel Zachmann via Cocoa-dev 
>>  wrote:
>> 
>> Thanks a million to everyone who has shared insights, hints, and advice on 
>> this.
>> 
>> I have restructured my code, so now I do the heavy lifting of loading images 
>> in a serial dispatch queue.
>> However, there is still sometimes some stuttering visible in the animation 
>> of the images.
>> Does anyone have an idea what might be causing it?
>> 
>> Here is the current structure of my code, given in sort of a pseudo-code:
>> 
>> -animateOneframe:
>> // essentially, this gets called when the next image is to be displayed
>> current_image_ = prefetched_image_;  // these are CGImageRef's
>> dispatch_async( prefetch_queue_, ^{
>>   [self loadNextImage];
>> } );
>> create a new CALayer, 
>> assign the current_image_ as content, 
>> create an animation for the layer,
>> add the layer to the layer hierarchy
>> 
>> In -loadNextImage, I am doing all the heavy lifting of loading images
>> (and the not-so-heavy), such as:
>> prefetched_image_ = nil;
>> CGImageSourceGetStatus
>> CGImageSourceCopyPropertiesAtIndex
>> CGImageSourceCreateThumbnailAtIndex
>> imageByApplyingOrientation
>> createCGImage
>> prefetched_image_ = new image
>> 
>> (I know there is some potential race condition here, but that is not of 
>> concern to me right now.)
>> 
>> Overall, I get the impression that it is "better" (less stuttering),
>> but sometimes there is still a stuttering in the animation when the app
>> makes a transition from one image to the next one.
>> 
>> How could that be? 
>> 
>> Using Instruments, I can see this in the "heaviest stack trace" when CPU 
>> usage is high in the main thread:
>> 
>> 41 CoreFoundation 3897.0  __CFRunLoopDoObservers
>> 40 CoreFoundation 3897.0  
>> __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
>> 39 QuartzCore 3896.0  
>> CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, 
>> void*)
>> 38 QuartzCore 3896.0  CA::Transaction::commit()
>> 37 QuartzCore 3895.0  CA::Context::commit_transaction(CA::Transaction*, 
>> double)
>> 36 QuartzCore 3895.0  CA::Layer::prepare_commit(CA::Transaction*)
>> 35 QuartzCore 3895.0  CA::Render::prepare_image(CGImage*, CGColorSpace*, 
>> unsigned int, double)
>> 34 QuartzCore 3895.0  CA::Render::copy_image(CGImage*, CGColorSpace*, 
>> unsigned int, double, double)
>> 33 QuartzCore 3895.0  CA::Render::(anonymous 
>> namespace)::create_image_by_rendering(CGImage*, CGColorSpace*, unsigned int, 
>> double, CA::Render::ImageCopyType)
>> 
>> Are these functions the culprits? How can I make them get executed in the 
>> background?
>> 
>> 
>> All insights will be highly appreciated.
>> 
>> Best regards, Gabriel
>> 
>> ___
>> 
>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>> 
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>> 
>> Help/Unsubscribe/Update your Subscription:
>> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
>> 
>> This email sent to z...@mac.com
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to

Re: Concurrent loading of images ?

2020-05-12 Thread Alex Zavatone via Cocoa-dev
Care to post a video on a Google drive so that we can see it?

One of my tricks (not just mine) is to have a 3 slots of for images, not just 
2.  When a new image loads, take the foreground one that is blended in to 100%, 
put an identical one ahead of it.  Make the changes to the new and old images 
behind it, then hide that foreground image.

You’re actually using a copy of the foreground image as a mask and you perform 
the swap behind it, then update the screen, then remove the top level one and 
refresh again. 

This is if I’m understanding what you’re going properly.

I’d expect that Apple’s video system to actually handle this if it still triple 
buffers, but it’s been 25 years since I read the docs on the Mac’s video 
subsystem.


In the mean time, add logging code that you can put breatpoints on and take a 
screen grab when you log.  That should help.

Cheers,
Alex Zavatone

> On May 12, 2020, at 3:27 PM, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> Thanks a million to everyone who has shared insights, hints, and advice on 
> this.
> 
> I have restructured my code, so now I do the heavy lifting of loading images 
> in a serial dispatch queue.
> However, there is still sometimes some stuttering visible in the animation of 
> the images.
> Does anyone have an idea what might be causing it?
> 
> Here is the current structure of my code, given in sort of a pseudo-code:
> 
> -animateOneframe:
>  // essentially, this gets called when the next image is to be displayed
>  current_image_ = prefetched_image_;  // these are CGImageRef's
>  dispatch_async( prefetch_queue_, ^{
>[self loadNextImage];
>  } );
>  create a new CALayer, 
>  assign the current_image_ as content, 
>  create an animation for the layer,
>  add the layer to the layer hierarchy
> 
> In -loadNextImage, I am doing all the heavy lifting of loading images
> (and the not-so-heavy), such as:
>  prefetched_image_ = nil;
>  CGImageSourceGetStatus
>  CGImageSourceCopyPropertiesAtIndex
>  CGImageSourceCreateThumbnailAtIndex
>  imageByApplyingOrientation
>  createCGImage
>  prefetched_image_ = new image
> 
> (I know there is some potential race condition here, but that is not of 
> concern to me right now.)
> 
> Overall, I get the impression that it is "better" (less stuttering),
> but sometimes there is still a stuttering in the animation when the app
> makes a transition from one image to the next one.
> 
> How could that be? 
> 
> Using Instruments, I can see this in the "heaviest stack trace" when CPU 
> usage is high in the main thread:
> 
>  41 CoreFoundation 3897.0  __CFRunLoopDoObservers
>  40 CoreFoundation 3897.0  
> __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
>  39 QuartzCore 3896.0  
> CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
>  38 QuartzCore 3896.0  CA::Transaction::commit()
>  37 QuartzCore 3895.0  CA::Context::commit_transaction(CA::Transaction*, 
> double)
>  36 QuartzCore 3895.0  CA::Layer::prepare_commit(CA::Transaction*)
>  35 QuartzCore 3895.0  CA::Render::prepare_image(CGImage*, CGColorSpace*, 
> unsigned int, double)
>  34 QuartzCore 3895.0  CA::Render::copy_image(CGImage*, CGColorSpace*, 
> unsigned int, double, double)
>  33 QuartzCore 3895.0  CA::Render::(anonymous 
> namespace)::create_image_by_rendering(CGImage*, CGColorSpace*, unsigned int, 
> double, CA::Render::ImageCopyType)
> 
> Are these functions the culprits? How can I make them get executed in the 
> background?
> 
> 
> All insights will be highly appreciated.
> 
> Best regards, Gabriel
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-12 Thread Gabriel Zachmann via Cocoa-dev
Thanks a million to everyone who has shared insights, hints, and advice on this.

I have restructured my code, so now I do the heavy lifting of loading images in 
a serial dispatch queue.
However, there is still sometimes some stuttering visible in the animation of 
the images.
Does anyone have an idea what might be causing it?

Here is the current structure of my code, given in sort of a pseudo-code:

-animateOneframe:
  // essentially, this gets called when the next image is to be displayed
  current_image_ = prefetched_image_;   // these are CGImageRef's
  dispatch_async( prefetch_queue_, ^{
[self loadNextImage];
  } );
  create a new CALayer, 
  assign the current_image_ as content, 
  create an animation for the layer,
  add the layer to the layer hierarchy

In -loadNextImage, I am doing all the heavy lifting of loading images
(and the not-so-heavy), such as:
  prefetched_image_ = nil;
  CGImageSourceGetStatus
  CGImageSourceCopyPropertiesAtIndex
  CGImageSourceCreateThumbnailAtIndex
  imageByApplyingOrientation
  createCGImage
  prefetched_image_ = new image

(I know there is some potential race condition here, but that is not of concern 
to me right now.)

Overall, I get the impression that it is "better" (less stuttering),
but sometimes there is still a stuttering in the animation when the app
makes a transition from one image to the next one.

How could that be? 

Using Instruments, I can see this in the "heaviest stack trace" when CPU usage 
is high in the main thread:

  41 CoreFoundation 3897.0  __CFRunLoopDoObservers
  40 CoreFoundation 3897.0  
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
  39 QuartzCore 3896.0  
CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
  38 QuartzCore 3896.0  CA::Transaction::commit()
  37 QuartzCore 3895.0  CA::Context::commit_transaction(CA::Transaction*, 
double)
  36 QuartzCore 3895.0  CA::Layer::prepare_commit(CA::Transaction*)
  35 QuartzCore 3895.0  CA::Render::prepare_image(CGImage*, CGColorSpace*, 
unsigned int, double)
  34 QuartzCore 3895.0  CA::Render::copy_image(CGImage*, CGColorSpace*, 
unsigned int, double, double)
  33 QuartzCore 3895.0  CA::Render::(anonymous 
namespace)::create_image_by_rendering(CGImage*, CGColorSpace*, unsigned int, 
double, CA::Render::ImageCopyType)

Are these functions the culprits? How can I make them get executed in the 
background?


All insights will be highly appreciated.

Best regards, Gabriel

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-10 Thread Jens Alfke via Cocoa-dev


> On May 8, 2020, at 2:53 PM, Gabriel Zachmann  wrote:
> 
> But in my case, I really have just one task, so the queue would - at most - 
> contain one task at a time.

You have to consider the case where the user is flipping through images faster 
than you can load them. In that case you do get multiple tasks piling up, or 
else you have to be able to abort the current task. I don't think you can abort 
a CoreGraphics call, though, so the best you could do is check for an abort in 
between two calls.

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Georg Seifert via Cocoa-dev
The last time I used layers to draw images it made a HUGE difference if the 
image was pixel perfect matching the size of the layer. If the image needed 
scaling, it was quite slow (I had really tiny images, but a lot of them).

g

> Am 9. May 2020 um 19:16 schrieb Steve Mills via Cocoa-dev 
> :
> 
>> On May 9, 2020, at 12:13, Gabriel Zachmann via Cocoa-dev 
>>  wrote:
>> 
>> Would that really make the background (worker) thread execute all that 
>> internal copying/decoding of images in the *background* thread?
>> 
>> I am asking because, currently, all this stuff gets executed in the main 
>> thread invoked by some observer.
>> And, after all, even a background thread eventually has to put the new image 
>> in the layer hierarchy, which, I fear, will cause the heavy lifting to be 
>> done by the main thread, again.
> 
> The point is, yes, the worker thread would be handling the image manipulation 
> to resize it to something that lets the main drawing thread work more 
> efficiently.
> 
> Steve via iPad
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/georg.seifert%40gmx.de
> 
> This email sent to georg.seif...@gmx.de

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Jim Crate via Cocoa-dev

> On May 9, 2020, at 07:41, Gabriel Zachmann  wrote:
> 
> 
>> Also, if you’re already getting a CGImageRef using 
>> CGImageSourceCreateImageAtIndex, why not just set imgLayer.contents to the 
>> CGImageRef? 
> 
> sorry, my previous response regarding this was incomplete. What I am doing is 
> this, in order to get the EXIF orientation right:
> 
> CIImage * image = [CIImage imageWithCGImage: imageRef];
> CIImage * orientedimage = [image imageByApplyingOrientation: 
> (CGImagePropertyOrientation) img_orientation];
> NSCIImageRep * nsimgrep = [NSCIImageRep imageRepWithCIImage: 
> orientedimage];
> NSImage * nsImage = [[NSImage alloc] initWithSize: nsimgrep.size];
> [nsImage addRepresentation: nsimgrep];
> CALayer * imgLayer= [CALayer layer]; 
> imgLayer.contents = nsImage;
> 
> Still, is there a better way?
> 
> Best regards, Gabriel

I’m not at my computer now, but if you load the image using the thumbnail 
option it will give you a properly oriented image. I’ll check the specific 
options when I get home and can look at the code. 

If you’re using CIImage anyway, you can render it back to a CGImageRef with a 
bitmap context, and that can be done in a separate thread as well. Then you 
have a rendered bitmap ready to assign to your CALayer contents property. 

Jim Crate

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Steve Mills via Cocoa-dev
> On May 9, 2020, at 12:13, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> Would that really make the background (worker) thread execute all that 
> internal copying/decoding of images in the *background* thread?
> 
> I am asking because, currently, all this stuff gets executed in the main 
> thread invoked by some observer.
> And, after all, even a background thread eventually has to put the new image 
> in the layer hierarchy, which, I fear, will cause the heavy lifting to be 
> done by the main thread, again.

The point is, yes, the worker thread would be handling the image manipulation 
to resize it to something that lets the main drawing thread work more 
efficiently.

Steve via iPad

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
> Time to learn some more about the frameworks you’re using then :)

:-)

> People have long dealt with this on iOS by doing tricks like first drawing 
> that image to a 1x1 bitmap on a worker thread before sending it on to the UI.

Would that really make the background (worker) thread execute all that internal 
copying/decoding of images in the *background* thread?

I am asking because, currently, all this stuff gets executed in the main thread 
invoked by some observer.
And, after all, even a background thread eventually has to put the new image in 
the layer hierarchy, which, I fear, will cause the heavy lifting to be done by 
the main thread, again.

Can you point me to some resources ? or examples that have solved this issue?

Best regards, Gabriel


> You have to do something along these lines (as far as I’m aware) to prompt 
> the first decode of the image to happen. After that, drawing it will be much 
> faster.
> 
> Mike.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Steve Mills via Cocoa-dev
> On May 9, 2020, at 08:51, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> 
>> 
>> 
>> Try Instruments. Apple have written a measuring tool for a reason :)
> 
> Thanks for the hint.
> 
> I've done that.
> In the Heaviest Stack Trace, I am seeing functions like 
> CA::Transcation::commit()
> CA::Render::copy_image(..)
> CI::recursive_tile(..)
> etc

If an image is huge and/or highres, it’s naturally going to take more time to 
render. I’d experiment and see if pre-sizing images before passing them onto 
the layer will be more efficient. Probably not, but it seems like some parts of 
the various Mac image frameworks do a better job of scaling than others.

Steve via iPad

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
> 
> Try Instruments. Apple have written a measuring tool for a reason :)

Thanks for the hint.

I've done that.
In the Heaviest Stack Trace, I am seeing functions like 
CA::Transcation::commit()
CA::Render::copy_image(..)
CI::recursive_tile(..)
etc

None of these functions seems to get invoked (indirectly) by any of my code.
Instead, they all seem to be called (indirectly) by _CFRunLoopDoObservers (in 
the main thread).

So, I feel a bit stumped.
What can I do?

It seems that somehow I need to make all this stuff happen in the background -
but how?


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Georg Seifert via Cocoa-dev
Have you profiled this? The first thing I would to is run that in Instruments.

Georg


> Am 9. May 2020 um 14:44 schrieb Gabriel Zachmann via Cocoa-dev 
> :
> 
> Again, thanks a lot for all the helpful hints.
> 
> Before restructuring my code, I did a few timings, using a set of test images 
> ranging in size from 30 through 300 MB.
> I used mach_absolute_time() for this experiment.
> And now, I am confused.
> 
> These are the execution times I have found for some of the methods that I 
> invoke in the process of loading and displaying the next image:
> 
> CGImageSourceCreateWithURL: 0.4-1.4 millisec
> CGImageSourceGetStatus: 10-600  microsec
> CGImageSourceCopyPropertiesAtIndex: 0.8-9   millisec 
> CGImageSourceCreateImageAtIndex:15  microsec
> convertToNSImage (*):   25  microsec
> imgLayer.contents = nsimage:1-5 microsec
> removeFromSuperlayer:   0.1 microsec
> addSublayer:5-10microsec
> 
> (*): this is a wrapper method of mine that does a few calls to 
> CIImage/NSImage/NSCIImageRep methods.
> 
> Overall, none of the methods I invoke seems to incur a long execution time.
> Yet, there is a noticeable lag when my app switches from one image to the 
> next one.
> I can tell because all layers have an animation assigned.
> Sometimes , there is even a stutter in the animation itself.
> 
> But it doesn't seem like it makes sense at this point to load images in a 
> concurrent/background dispatch queue, does it?
> 
> So, I am confused: where is the lag coming from?
> 
> Any ideas how I might be able to prevent the lag/stutter when loading and 
> switching to big images?
> 
> 
> Best, G.
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/georg.seifert%40gmx.de
> 
> This email sent to georg.seif...@gmx.de

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
Again, thanks a lot for all the helpful hints.

Before restructuring my code, I did a few timings, using a set of test images 
ranging in size from 30 through 300 MB.
I used mach_absolute_time() for this experiment.
And now, I am confused.

These are the execution times I have found for some of the methods that I 
invoke in the process of loading and displaying the next image:

CGImageSourceCreateWithURL: 0.4-1.4 millisec
CGImageSourceGetStatus: 10-600  microsec
CGImageSourceCopyPropertiesAtIndex: 0.8-9   millisec 
CGImageSourceCreateImageAtIndex:15  microsec
convertToNSImage (*):   25  microsec
imgLayer.contents = nsimage:1-5 microsec
removeFromSuperlayer:   0.1 microsec
addSublayer:5-10microsec

(*): this is a wrapper method of mine that does a few calls to 
CIImage/NSImage/NSCIImageRep methods.

Overall, none of the methods I invoke seems to incur a long execution time.
Yet, there is a noticeable lag when my app switches from one image to the next 
one.
I can tell because all layers have an animation assigned.
Sometimes , there is even a stutter in the animation itself.

But it doesn't seem like it makes sense at this point to load images in a 
concurrent/background dispatch queue, does it?

So, I am confused: where is the lag coming from?

Any ideas how I might be able to prevent the lag/stutter when loading and 
switching to big images?


Best, G.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
> Also, if you’re already getting a CGImageRef using 
> CGImageSourceCreateImageAtIndex, why not just set imgLayer.contents to the 
> CGImageRef? 

sorry, my previous response regarding this was incomplete. What I am doing is 
this, in order to get the EXIF orientation right:

CIImage * image = [CIImage imageWithCGImage: imageRef];
CIImage * orientedimage = [image imageByApplyingOrientation: 
(CGImagePropertyOrientation) img_orientation];
NSCIImageRep * nsimgrep = [NSCIImageRep imageRepWithCIImage: orientedimage];
NSImage * nsImage = [[NSImage alloc] initWithSize: nsimgrep.size];
[nsImage addRepresentation: nsimgrep];
CALayer * imgLayer= [CALayer layer]; 
imgLayer.contents = nsImage;

Still, is there a better way?

Best regards, Gabriel

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
> 
> Also, if you’re already getting a CGImageRef using 
> CGImageSourceCreateImageAtIndex, why not just set imgLayer.contents to the 
> CGImageRef? 

Good point .  What I am doing right now is:

NSImage * nsimage = [self convertToNSImage: img withOrientation: 
img_orientation];
CALayer * imgLayer= [CALayer layer]; 
imgLayer.contents = nsimage;

The reason for that is that otherwise (IIRC) the EXIF orientation flags would 
not be heeded correctly by the CALayer.

Is there a better way to achieve this?

Best, G.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-09 Thread Gabriel Zachmann via Cocoa-dev
> I would add, that for a long running process, open ended work, or task, I 
> would favor a thread.  But for short and finite items I would favor 
> GCD/NSOperationQueue.  
> 
> Are you going to only load one image, the next image, in this concurrent 
> loading scenario?  Or, will you be loading many images and caching them?  

No, just one (next) image.
That will then get displayed about a minute later, at which point the image 
after that should get prefetched.

> 
> I would imaging looking one or two ahead would be the choice.  

Yes, I am planning to look ahead just one image.
That's why I thought a whole queue might be overdoing it for just one task that 
takes usually just a few milliseconds, and occasionally 1-2 seconds.

But if you say that for such one-off tasks, an NSOperationQueue is better, I'll 
go with that approach.

And thanks a lot to everybody for sharing their insights and hints.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread James Crate via Cocoa-dev
On May 8, 2020, at 6:00 PM, Gabriel Zachmann via Cocoa-dev 
 wrote:
> 
>> Sure. Just be aware that if you're using NSImage, simply loading an NSImage 
>> does not rasterize it; the class tries to be 'lazy' about doing work. So 
>> your background task should explicitly render it, e.g. into an 
>> NSBitmapImageRep.
> 
> I am using CGImageSourceCreateImageAtIndex and related functions.
> But I am still unclear which function actually takes the time.
> Maybe it is only when I create the CALayer like this?
> 
> CALayer * imgLayer= [CALayer layer]; 
> imgLayer.contents = nsimage;

Reading a 50MB image will definitely take some time, so preloading the image 
will definitely help. I’ve usually used an NSOperationQueue but my apps working 
with images can sometimes be loading hundreds of images and NSOperationQueue 
has an option to limit the number of operations run concurrently.  Since you’ll 
only be loading the next image then a single GCD dispatch would work just as 
well.

Also, if you’re already getting a CGImageRef using 
CGImageSourceCreateImageAtIndex, why not just set imgLayer.contents to the 
CGImageRef? 

Jim Crate

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Alex Zavatone via Cocoa-dev
Using a queue is part of GCD.  You should probably not use the main queue since 
that is analogous to the main thread and the main thread is meant for updating 
the UI.

The good thing here is that you can sort of preload the next image in a queue 
after your last one has displayed. 

With a dispatchQueue, the idea here is that you have lots of tasks that you 
want to get done and you want the previous task to complete, then start the 
next one and so on and so on. You probably don’t need to do that for this 
application.

If I were doing this in Objective-C, I’d fire off a “preload” on an async 
dispatch to a block.  Something like this.

// create a queue to load the image
dispatch_group_t d_group = dispatch_group_create();
dispatch_queue_t bg_queue = 
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_async(d_group, bg_queue, ^{
NSLog(@“preloading");
Do that image loading here
});


If you did want to do something on the main queue, you can do it like this.

dispatch_async(dispatch_get_main_queue(), ^{
Do your main thread updates here
}

If you want to use a serial queue that doesn’t block the main thread you can do 
it like this.

// Dispatch the rest of session setup to the sessionQueue so that the main 
queue isn't blocked.
dispatch_queue_t sessionQueue = dispatch_queue_create("session queue", 
DISPATCH_QUEUE_SERIAL);
[self setSessionQueue:sessionQueue];

dispatch_async(sessionQueue, ^{
Do stuff here, but you want to read up on dipatch queues to see the 
best approach.
}


There’s lots of fun that you can have using these queues and GCD.  The trick is 
finding the approaches that suit your needs.

Hope these help.  

> On May 8, 2020, at 4:53 PM, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
>>  I second the use of GCD.  Its also considerably simpler than NSThread, 
>> NSOperationQueue/NSOperation et al. This is the kind of operation that GCD 
>> was invented for.
> 
> Thanks a lot for your response(s).
> 
> To me a queue suggests that you have lots and lots of tasks arriving from the 
> producer , which you need to buffer in queue, so that the consumer can work 
> on it one task at a time.
> 
> But in my case, I really have just one task, so the queue would - at most - 
> contain one task at a time.
> So, why not start the task right away using NSThread or NSOperation?
> 
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Sandor Szatmari via Cocoa-dev

> On May 8, 2020, at 15:13, Rob Petrovec via Cocoa-dev 
>  wrote:
> 
> 
> 
>>> On May 8, 2020, at 12:19 PM, Jens Alfke via Cocoa-dev 
>>>  wrote:
>>> 
>>> 
>>> 
 On May 8, 2020, at 9:53 AM, Gabriel Zachmann via Cocoa-dev 
  wrote:
>>> 
>>> So, I was thinking, maybe it helps to load the next image concurrently, 
>>> while the current one is still being displayed.
>> 
>> Sure. Just be aware that if you're using NSImage, simply loading an NSImage 
>> does not rasterize it; the class tries to be 'lazy' about doing work. So 
>> your background task should explicitly render it, e.g. into an 
>> NSBitmapImageRep.
>> 
>>> I also read about the GCD's dispatch queues, but it seems to me that this 
>>> would not be the suitable approach since I always only have one task 
>>> running concurrently to the main thread.
>> 
>> Why not? Dispatch queues are always available. (The main thread is simply a 
>> special queue.) You can run the background task by creating a single 
>> dispatch queue and then using dispatch_async to call a block that does the 
>> work. The end of the block would call dispatch_async back to the main queue 
>> and pass the image as a parameter.
>I second the use of GCD.  Its also considerably simpler than NSThread, 
> NSOperationQueue/NSOperation et al.  This is the kind of operation that GCD 
> was invented for.

I would add, that for a long running process, open ended work, or task, I would 
favor a thread.  But for short and finite items I would favor 
GCD/NSOperationQueue.  

Are you going to only load one image, the next image, in this concurrent 
loading scenario?  Or, will you be loading many images and caching them?  

I would imaging looking one or two ahead would be the choice.  I’m just trying 
to understand the need/use case.  If there’s lots of overhead that can be 
reduced to a one time effort than maybe a thread is better.  If not maybe a 
one-off throw-it-in-a-queue and be done with it approach is better?

Sandor

> 
> —Rob
> 
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/admin.szatmari.net%40gmail.com
> 
> This email sent to admin.szatmari@gmail.com
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Gabriel Zachmann via Cocoa-dev
> Sure. Just be aware that if you're using NSImage, simply loading an NSImage 
> does not rasterize it; the class tries to be 'lazy' about doing work. So your 
> background task should explicitly render it, e.g. into an NSBitmapImageRep.

I am using CGImageSourceCreateImageAtIndex and related functions.
But I am still unclear which function actually takes the time.
Maybe it is only when I create the CALayer like this?

CALayer * imgLayer= [CALayer layer]; 
imgLayer.contents = nsimage;


> 
> Why not? Dispatch queues are always available. (The main thread is simply a 
> special queue.) You can run the background task by creating a single dispatch 
> queue and then using dispatch_async to call a block that does the work. The 
> end of the block would call dispatch_async back to the main queue and pass 
> the image as a parameter.

Could you give a few more specific hints?


Best regards, Gabriel


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Gabriel Zachmann via Cocoa-dev
>   I second the use of GCD.  Its also considerably simpler than NSThread, 
> NSOperationQueue/NSOperation et al. This is the kind of operation that GCD 
> was invented for.

Thanks a lot for your response(s).

To me a queue suggests that you have lots and lots of tasks arriving from the 
producer , which you need to buffer in queue, so that the consumer can work on 
it one task at a time.

But in my case, I really have just one task, so the queue would - at most - 
contain one task at a time.
So, why not start the task right away using NSThread or NSOperation?


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images?

2020-05-08 Thread João Varela via Cocoa-dev
> I also read about the GCD's dispatch queues, but it seems to me that this
would not be the suitable approach since I always only have one task
running concurrently to the main thread.

>
> Why not? Dispatch queues are always available. (The main thread is simply
> a special queue.) You can run the background task by creating a single
> dispatch queue and then using dispatch_async to call a block that does the
> work. The end of the block would call dispatch_async back to the main queue
> and pass the image as a parameter.


I could not agree more with Jens. Great Central Dispatch has been a big
boon. Before GCD, I would not touch multithreaded code with a ten-foot
pole. Now I use it everyday and I can increase responsiveness as never
before. I would definitely take a look at it. You can load images with a
background thread and then when the loading is done you can dispatch it to
the main queue for display. It has never been so easy to do that.

João


>
>
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Rob Petrovec via Cocoa-dev


> On May 8, 2020, at 12:19 PM, Jens Alfke via Cocoa-dev 
>  wrote:
> 
> 
> 
>> On May 8, 2020, at 9:53 AM, Gabriel Zachmann via Cocoa-dev 
>>  wrote:
>> 
>> So, I was thinking, maybe it helps to load the next image concurrently, 
>> while the current one is still being displayed.
> 
> Sure. Just be aware that if you're using NSImage, simply loading an NSImage 
> does not rasterize it; the class tries to be 'lazy' about doing work. So your 
> background task should explicitly render it, e.g. into an NSBitmapImageRep.
> 
>> I also read about the GCD's dispatch queues, but it seems to me that this 
>> would not be the suitable approach since I always only have one task running 
>> concurrently to the main thread.
> 
> Why not? Dispatch queues are always available. (The main thread is simply a 
> special queue.) You can run the background task by creating a single dispatch 
> queue and then using dispatch_async to call a block that does the work. The 
> end of the block would call dispatch_async back to the main queue and pass 
> the image as a parameter.
I second the use of GCD.  Its also considerably simpler than NSThread, 
NSOperationQueue/NSOperation et al.  This is the kind of operation that GCD was 
invented for.

—Rob


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Jens Alfke via Cocoa-dev


> On May 8, 2020, at 9:53 AM, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> So, I was thinking, maybe it helps to load the next image concurrently, while 
> the current one is still being displayed.

Sure. Just be aware that if you're using NSImage, simply loading an NSImage 
does not rasterize it; the class tries to be 'lazy' about doing work. So your 
background task should explicitly render it, e.g. into an NSBitmapImageRep.

> I also read about the GCD's dispatch queues, but it seems to me that this 
> would not be the suitable approach since I always only have one task running 
> concurrently to the main thread.

Why not? Dispatch queues are always available. (The main thread is simply a 
special queue.) You can run the background task by creating a single dispatch 
queue and then using dispatch_async to call a block that does the work. The end 
of the block would call dispatch_async back to the main queue and pass the 
image as a parameter.

(Or you could use NSOperationQueue and NSOperation, although I've always found 
those classes unnecessarily complicated for simple tasks.)

—Jens
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Alex Zavatone via Cocoa-dev

Does this seem related?

https://9to5mac.com/2020/04/28/new-bug-found-in-macos-can-quickly-fill-up-storage-when-importing-photos-with-image-capture/

"The problem discovered by the NeoFinder team is that the Mac adds 1.5MB of 
empty data to each converted photo, making the imported files larger for no 
reason. By looking inside these photos through a Hex-Editor, you can find a 
section full of zeroes, which results in unnecessarily larger files.”

I know you’re not capturing images, just loading them, but It’s pretty 
suspiciously similar.

> On May 8, 2020, at 11:53 AM, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> Sometimes, when it switches from one image to the next, there is a noticeable 
> lag when the file size of the next image is very big, say, 50 MB or more.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Gabriel Zachmann via Cocoa-dev
Thanks for the question:  MacOS.

> 
> iOS or MacOS?



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Concurrent loading of images ?

2020-05-08 Thread Alex Zavatone via Cocoa-dev
iOS or MacOS?

> On May 8, 2020, at 11:53 AM, Gabriel Zachmann via Cocoa-dev 
>  wrote:
> 
> I have kind of a slide-show app.
> 
> Sometimes, when it switches from one image to the next, there is a noticeable 
> lag when the file size of the next image is very big, say, 50 MB or more.
> Sometimes, it seems that loading the image takes 1-2 seconds.
> 
> So, I was thinking, maybe it helps to load the next image concurrently, while 
> the current one is still being displayed.
> 
> My question is: should I spawn a thread (using NSThreads' 
> detachNewThreadSelector), load the image in that thread, then exit the 
> thread? (no run loop)
> 
> Or should I use NSObject's performSelectorInBackground ?
> 
> I also read about the GCD's dispatch queues, but it seems to me that this 
> would not be the suitable approach since I always only have one task running 
> concurrently to the main thread.
> 
> What do you think?
> 
> Best regards, Gabriel
> 
> ___
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
> 
> This email sent to z...@mac.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com