Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Faster Image Capture #2713

Closed
wants to merge 30 commits into from
Closed

Conversation

rajat2004
Copy link
Contributor

@rajat2004 rajat2004 commented May 23, 2020

Rebased and working version of #2472. Needs more testing

See some benchmarks on my system here - #2472 (comment)

One thing I noticed is that with the PR, we're getting 4 channels RGBA instead of 3 in master, this now becomes inline with Unity which is also giving 4 channels

My later commits might be a bit haphazard, will clean up later

Binaries - https://drive.google.com/open?id=14t9rmTGR3Au0R5V8GoF5DfYKYcLOJSAU
Linux - -opengl gives correct images, default Vulkan gives scrambled data, see comment below

On Linux, with binary, I'm getting about 2x improvement from ~15 (latest release) to ~35 FPS on my system

Image types Scene, Segmentation, Normals work correctly, however Depth images is giving 8 channels somehow?

If someone wants to test using this PR from source, use this branch - https://github.com/rajat2004/AirSim/tree/faster_img_cap_test (It's updated to latest master, and will be pushing any commits there first)

Nicholas Gyde (Collabera) and others added 23 commits March 25, 2020 16:38
…more. Buffer pool might be useful for other things.
…er pool to the render thread so it can ask for the correct size of dest buffer when src buffer is known.
…e-0 buffer back into the response's image_data_uint8, which then returns that useless buffer to the buffer pool. Since RPC can't take over the unique_ptr that manages our buffer, we should send RPC a copy.
@rajat2004 rajat2004 mentioned this pull request May 23, 2020
@rajat2004 rajat2004 marked this pull request as draft May 24, 2020 12:34
@rajat2004
Copy link
Contributor Author

rajat2004 commented May 25, 2020

Update: The PR has been tested to be working correctly on Windows, on Linux, with RLM_ReadOnly it crashes due to an assert in the Engine code. RLM_WriteOnly gives garbage data on both Win & Linux.
Commented out the assert in Engine code in Linux, but still getting garbage data with RLM_ReadOnly. Working correctly with OpenGL, however FPS drops than with Vulkan, though still higher than master. Seems to be a bug in Vulkan for Linux, maybe will post on some UE4 forums

Linux testing has been done with both 4.24 & 4.25

Any suggestions & testing would be great!

Post on UE4 forums - https://answers.unrealengine.com/questions/961968/view.html, https://forums.unrealengine.com/development-discussion/c-gameplay-programming/1767926-rhilocktexture2d-returns-garbage-data-with-vulkan-on-linux

@SijmenHuizenga
Copy link

This is amazing. Thank you so much for this amazing work <3

At our repo we have been trying to get this to work as well. We are on linux with vulkan, commented out the assert and are using RLM_ReadOnly. We are getting garbage data as well. What is most peculiar is that the image (garbage data) does not change when driving around. We will try to get it to work some more but might have to move to Windows.

@WouterJansen
Copy link
Contributor

WouterJansen commented Jun 15, 2020

I tested this out. Performance does seem amazing now from a first glance. However I noticed a few issues. Do note I'm on a pretty old version of AirSim (I'd say the version from mid 2019 for Unreal 4.18) and am using 4.22 atm.

In the old version the RenderRequest functionality used BGR instead of RGB, which I always thought was odd (some CV2 specific choice?) so I changed it to RGB by changing the following:

 for (const auto& item : results[i]->bmp) {	
                        *ptr++ = item.B;	
                        *ptr++ = item.G;	
                        *ptr++ = item.R;	
 }

to RGB. This made my ROS code a lot easier to use. I couldn't not find in this PR how it was done now. Would be great if you could let me know if I could change it as well to RGB.

I also experienced a crash almost on every run now now. Again, I'm on 4.22 with a pretty old version of Airsim with many custom changes so not sure how relevant this crash report is. Was running from Editor. I'll let you know if I get more information on it.

Using this request setup:

requests = []
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.Scene, False, False))
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.Segmentation, False, False))
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.DepthPlanner, True, False))
responses = client.simGetImages(requests)

Got a breakpoint crash here:

FTextureRenderTargetResource* UTextureRenderTarget::GameThread_GetRenderTargetResource()
{
	check( IsInGameThread() );
	return static_cast< FTextureRenderTargetResource*>( Resource );
}

the exception:

Exception thrown: read access violation.
**this** was nullptr.

callstack:

>	UE4Editor-Engine.dll!UTextureRenderTarget::GameThread_GetRenderTargetResource() Line 46	C++
 	UE4Editor-Renderer.dll!FScene::UpdateSceneCaptureContents(USceneCaptureComponent2D * CaptureComponent) Line 769	C++
 	UE4Editor-Engine.dll!USceneCaptureComponent::UpdateDeferredCaptures(FSceneInterface * Scene) Line 393	C++
 	UE4Editor-Renderer.dll!FRendererModule::BeginRenderingViewFamily(FCanvas * Canvas, FSceneViewFamily * ViewFamily) Line 3389	C++
 	UE4Editor-Engine.dll!UGameViewportClient::Draw(FViewport * InViewport, FCanvas * SceneCanvas) Line 1470	C++
 	UE4Editor-Engine.dll!FViewport::Draw(bool bShouldPresent) Line 1515	C++
 	UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1821	C++
 	UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 403	C++
 	UE4Editor.exe!FEngineLoop::Tick() Line 3967	C++
 	[Inline Frame] UE4Editor.exe!EngineTick() Line 62	C++
 	UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 168	C++
 	UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 261	C++
 	[External Code]	

I also get a lot of warnings related to bCaptureEveryFrame. Should this be turned off? To make it work I simply followed what was said here : #2536 (comment)_.
Warning: CaptureScene: Scene capture with bCaptureEveryFrame enabled was told to update - major inefficiency.

@rajat2004
Copy link
Contributor Author

@WouterJansen Thanks for the detailed testing!

Do note I'm on a pretty old version of AirSim (I'd say the version from mid 2019 for Unreal 4.18) and am using 4.22 atm.

When testing this PR, you're on the latest master (well, even more cutting edge). Testing with 4.22 is great since I haven't done that

In the old version the RenderRequest functionality used BGR instead of RGB, which I always thought was odd (some CV2 specific choice?)

OpenCV uses BGR as it's default order, so probably yes

This made my ROS code a lot easier to use. I couldn't find in this PR how it was done now. Would be great if you could let me know if I could change it as well to RGB.

This currently just copies the entire block of pixels rendered by UE, see this. So even I'm not sure how to do that, need to look into that. But should be possible to write a wrapper code after calling the API to convert to desired format.

I also experienced a crash almost on every run now now. Again, I'm on 4.22 with a pretty old version of Airsim with many custom changes so not sure how relevant this crash report is. Was running from Editor. I'll let you know if I get more information on it.

Using this request setup:

requests = []
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.Scene, False, False))
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.Segmentation, False, False))
requests.append(airsimpy.ImageRequest(front_center, airsim.ImageType.DepthPlanner, True, False))
responses = client.simGetImages(requests)

I also get a lot of warnings related to bCaptureEveryFrame. Should this be turned off? To make it work I simply followed what was said here : #2536 (comment)_.
Warning: CaptureScene: Scene capture with bCaptureEveryFrame enabled was told to update - major inefficiency.

I'm not seeing these on Linux at least, and been some time since I tested on Win. Maybe was introduced by the recent revert to the asset which was disabling the flag?
So just some queries about this part. Are you getting the crashes after disabling bCaptureEveryFrame? Or before as well? What was the performance difference before and after disabling it? @saihv Since you've worked on this before, might have insights on what this does.

Also, could the crash be happening due to a specific image type? If possible, can you check if commenting out, say the Depth image doesn't cause it to crash?
Crash could be happening due to UE 4.22 as well. I'll try to do some more testing soon on my system.

@WouterJansen
Copy link
Contributor

WouterJansen commented Jun 15, 2020

I'm not on the master, I'm on a older version of Airsim with just this PR implemented on top of it :)

The RGB/BGR thing was solved by just changing the encoding in my ROS publish of the image. Not a big deal just need to alter my ROS node.

I'll do some more testing to see if it's a particular image type that causes the crash.

I did not test before turning bCaptureEveryFrame on. I simply updated the camera blueprint as in that linked issue/comment to turn both those features on (Capture Every Frame and Always Persist Rendering State). I'll do some testing with turning on and off these settings.

I did notice another issue. Seems like turning on pixels_as_float returns a ImageResponse with no floating image information.
my request:
image
my response:
image
As you can see the response has pixels_as_float set to False image_data_float is empty. It also has compress turned on while my request had it disabled. Not sure if this was the case before this PR but floating point requests did work as expected before.

Edit: seems no matter what I do, compress is always True and pixels_as_float always False on my response.

@WouterJansen
Copy link
Contributor

Was doing another test. Now with only a scene capture (request:scene, compress=false,pixels_as_float=false).

Got a new crash in SparseArray.h:
Assertion failed: Index < GetMaxIndex() [File:d:\unrealengine\engine\source\runtime\core\public\Containers/SparseArray.h] [Line: 86]

> [Inline Frame] UE4Editor-Engine.dll!TSparseArray<TSetElement<FTickFunction *>,TSparseArrayAllocator<FDefaultAllocator,FDefaultBitArrayAllocator> >::AllocateIndex(int) Line 86 C++ UE4Editor-Engine.dll!TSparseArray<TSetElement<FTickFunction *>,TSparseArrayAllocator<FDefaultAllocator,FDefaultBitArrayAllocator> >::AddUninitialized() Line 125 C++ UE4Editor-Engine.dll!TSet<FTickFunction *,DefaultKeyFuncs<FTickFunction *,0>,FDefaultSetAllocator>::Emplace<FTickFunction * const &>(FTickFunction * const & Args, bool * bIsAlreadyInSetPtr) Line 510 C++ UE4Editor-Engine.dll!FTickTaskLevel::AddTickFunction(FTickFunction * TickFunction) Line 1111 C++ UE4Editor-Engine.dll!FTickFunction::SetTickFunctionEnable(bool bInEnabled) Line 1789 C++ UE4Editor-Engine.dll!UActorComponent::SetComponentTickEnabled(bool bEnabled) Line 862 C++ UE4Editor-Engine.dll!UActorComponent::Activate(bool bReset) Line 1524 C++ UE4Editor-AirSim.dll!APIPCamera::enableCaptureComponent(const msr::airlib::ImageCaptureBase::ImageType type, bool is_enabled) Line 447 C++ [Inline Frame] UE4Editor-AirSim.dll!APIPCamera::setCameraTypeEnabled(msr::airlib::ImageCaptureBase::ImageType) Line 248 C++ UE4Editor-AirSim.dll!UnrealImageCapture::getSceneCaptureImage(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & camera_name, msr::airlib::ImageCaptureBase::ImageType image_type, msr::airlib::ImageCaptureBase::ImageResponse & response) Line 33 C++ UE4Editor-AirSim.dll!PawnSimApi::getImages(const std::vector<msr::airlib::ImageCaptureBase::ImageRequest,std::allocator<msr::airlib::ImageCaptureBase::ImageRequest> > & requests, std::vector<msr::airlib::ImageCaptureBase::ImageResponse,std::allocator<msr::airlib::ImageCaptureBase::ImageResponse> > & responses) Line 191 C++ UE4Editor-AirSim.dll!msr::airlib::RpcLibServerBase::{ctor}::__l2::<lambda>(const std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> > & request_adapter, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & vehicle_name) Line 108 C++ [Inline Frame] UE4Editor-AirSim.dll!rpc::detail::call_helper<0>::call(msr::airlib::RpcLibServerBase::{ctor}::__l2::std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse> > <lambda>(const std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &) f, std::tuple<std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > &) Line 75 C++ [Inline Frame] UE4Editor-AirSim.dll!rpc::detail::call_helper<1>::call(msr::airlib::RpcLibServerBase::{ctor}::__l2::std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse> > <lambda>(const std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &)) Line 56 C++ [Inline Frame] UE4Editor-AirSim.dll!rpc::detail::call_helper<2>::call(msr::airlib::RpcLibServerBase::{ctor}::__l2::std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse> > <lambda>(const std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &)) Line 56 C++ [Inline Frame] UE4Editor-AirSim.dll!rpc::detail::call(msr::airlib::RpcLibServerBase::{ctor}::__l2::std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageResponse> > <lambda>(const std::vector<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest,std::allocator<msr::airlib_rpclib::RpcLibAdapatorsBase::ImageRequest> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &)) Line 84 C++ UE4Editor-AirSim.dll!rpc::detail::dispatcher::bind::__l2::<lambda>(const clmdep_msgpack::v2::object & args) Line 74 C++ [External Code]

@rajat2004
Copy link
Contributor Author

I'm not on the master, I'm on a older version of Airsim with just this PR implemented on top of it :)

Oh ok, that makes sense

I did notice another issue. Seems like turning on pixels_as_float returns a ImageResponse with no floating image information.
As you can see the response has pixels_as_float set to False image_data_float is empty. It also has compress turned on while my request had it disabled. Not sure if this was the case before this PR but floating point requests did work as expected before.

Edit: seems no matter what I do, compress is always True and pixels_as_float always False on my response.

I think it might just be due to some pieces being missed out during implementing this, such as this, float will need some looking into.

@rajat2004
Copy link
Contributor Author

Was doing another test. Now with only a scene capture (request:scene, compress=false,pixels_as_float=false).

Got a new crash in SparseArray.h:
Assertion failed: Index < GetMaxIndex() [File:d:\unrealengine\engine\source\runtime\core\public\Containers/SparseArray.h] [Line: 86]

This seems to be somewhat common crash, like this, could be due to 4.22? Not sure

@WouterJansen
Copy link
Contributor

WouterJansen commented Jun 15, 2020

I think it might just be due to some pieces being missed out during implementing this, such as this, float will need some looking into.

Ok that makes sense. Well I could work around the float not being implemented yet, but would be good to have back at some point.

Did some more testing, doesn't really seem to matter which camera type I use. Scene seems to make the crashes happen easily, just like all the others. Turning on and off Capture Every Frame and Always Persist Rendering State also made no difference. It's relatively random. It's more easy to trigger when looping it instead of the occasional request:

    while True:
        requests = []
        requests.append(airsimpy.ImageRequest("front_center", airsim.ImageType.Scene, False, False))
        responses = client.simGetImages(requests)
        time.sleep(0.1)

I'll keep an eye out on this PR. If these crashes are only an issue that I am having I guess it's worth a full update of my Airsim to the latest versions :)

@rajat2004
Copy link
Contributor Author

rajat2004 commented Jun 16, 2020

So am doing a bit of testing today, but yeah, am able to trigger crash similar to this - #2713 (comment)
Triggerring from here - https://github.com/microsoft/AirSim/blob/master/Unreal/Plugins/AirSim/Source/PIPCamera.cpp#L439

@WouterJansen regarding bCaptureEveryFrame, did you disable that in every camera type in the BP Editor? Since it needs to be done in all I think.
Should it actually be turned off though? It's description suggests it's better left on I think - Whether to update the capture's contents every frame. If disabled, the component will render once on load and then only when moved.

@WouterJansen
Copy link
Contributor

@WouterJansen regarding bCaptureEveryFrame, did you disable that in every camera type in the BP Editor? Since it needs to be done in all I think.
Should it actually be turned off though? It's description suggests it's better left on I think - Whether to update the capture's contents every frame. If disabled, the component will render once on load and then only when moved.

If I recall correctly, in my old version of AirSim bCaptureEveryFrame was turned off. So I turned it on to align with the current AirSim settings. I did attempt toggling it off and on to see if it was the cause of the crash but doesn't seem like it. And yeah, I think it should be turned on as you say as well.

@rajat2004
Copy link
Contributor Author

rajat2004 commented Jun 18, 2020

Worked on the float part a bit, my testing branch is here - https://github.com/rajat2004/AirSim/tree/faster_img_cap_test, compare against this branch can be seen here
What I did was to convert BufferPool to template and make image_data_float essentially equal to image_data_uint

I'm still confused about the float part a bit, just trying to lay down my thoughts here, please let me know where I am going wrong

  • All 3 Depth images are of float type by default, others are uint8
  • User can request any image to be of Float or non-Float type
  • If image data is float (requested or through image_type), it's present in image_data_float. Also pixels_as_float should be True in this case
  • User has to handle after getting the response, such as to access the correct field image_data_uint8 or image_data_float. For saving float data, we have to use write_pfm

For visualising the Depth image, it has to be called with pixels_as_float false, and then use image_data_uint8, no other way?

In my testing branch, right now the Depth images are of type float. User-requested data-type doesn't matter (which I think should be ok, they can be converted to one to other)
For some reason, I'm getting an 8 channel image, like when using get_pfm_array(), the error message - ValueError: cannot reshape array of size 294912 into shape (144,256)

@petergerten
Copy link

Is there currently any recommended branch or commit to use if I want to take a look at a working 'faster' version?

@rajat2004
Copy link
Contributor Author

@petergerten You could try out this or even https://github.com/rajat2004/AirSim/tree/faster_img_cap_test branch, the latter one has some more commits, but depth image still doesn't work, will try to bring it up-to-date and work on it. Any commits will be made on the faster_img_cap_test branch, and then will port them over to here
You can try out the binaries I've linked in the first comment if haven't already done so. Note that on Linux, running the binaries as well as in Editor will require -opengl since Vulkan gives garbage data for some reason

@rajat2004
Copy link
Contributor Author

@madratman @saihv I was working on the faster_img_cap_test branch, and was always getting a linking error after merging the master branch into it. After taking a long break and going through the commits, figured out that it was happening due to the recent changes in build.sh & AirSim.Build.cs to use precompiled AirLib in UE
The problem was that I had changed BufferPool to a template class in Airlib, objects of which were being used in UE code.This caused the linking error due to objects with the datatypes not being compiled when Airlib was built, and so definitions weren't found when linking.
I added a commit which reversed the change to Build.cs and build.sh, and now it compiles.

@madratman
Copy link
Contributor

madratman commented Jul 29, 2020

I think we should move BufferPool to the unreal/plugins part of the code, as it's only used in the Unreal part.
Using the precompiled AirLib is technically the more correct way of doing things, and also reduces iteration time in development.

@WouterJansen
Copy link
Contributor

Any luck with the crashes?

@rajat2004
Copy link
Contributor Author

@WouterJansen No, it's still crashing. It seems to be more frequent on Windows than Linux, people have tried out 15 min runs with the binary without crashing, the editor does crash more. Also if it crashes once, then it mostly crashes on the next run as well. There might be some deeper issue at hand here, since it's crashing where the campers is activated.
I was thinking of having a look at some other implementations, maybe Carla. Unfortunately I mostly won't be able to work on this for the next few days atleast

@WouterJansen
Copy link
Contributor

This is by far the current biggest bottleneck for me to use AirSim to the full potential.

As soon as I add more then 1 camera to my simGetImages() request it just gets exponentially worse. So something like a stereo depth camera with 4 requests (2xRGB+2xdepth) makes it only produce images at 3FPS on good hardware.

If any additional testing or help is required here I would love to assist.

@rajat2004
Copy link
Contributor Author

rajat2004 commented Sep 4, 2020

I'll maybe try to work on this over the weekend, anyone is more than welcome to try it out and figure out the problems, everything is open-source.
Just did a short-run on UE 4.25, doesn't seem to be crashing atleast on short runs. Win Binary

But fixing the crashes and making it work on Vulkan seems to be very difficult to me right now, any ideas or suggestions are welcome.
I also was thinking of a different short-tern approach separate from this PR, to collect the images in the request parallelly, UE has a ParallelFor method which might work

@phil333
Copy link

phil333 commented Sep 7, 2020

I'll maybe try to work on this over the weekend, anyone is more than welcome to try it out and figure out the problems, everything is open-source.
Just did a short-run on UE 4.25, doesn't seem to be crashing atleast on short runs. Win Binary

But fixing the crashes and making it work on Vulkan seems to be very difficult to me right now, any ideas or suggestions are welcome.
I also was thinking of a different short-tern approach separate from this PR, to collect the images in the request parallelly, UE has a ParallelFor method which might work

H rajat2004. At least from my side the ParallelFor method sounds interesting. One of my issues is that I am testing Stereo Cameras in Unreal, and the lack of synchronisation between multiple cameras is a major issue.

@rajat2004
Copy link
Contributor Author

I did try out the ParallelFor implementation but didn't work, the editor hangs, maybe cause the image rendering has to happen on the game thread, so running parallelly still won't work. Here's my branch - https://github.com/rajat2004/AirSim/tree/parallel-img-cap if anyone wants to test, note that code is quite messy


// Disable camera after capturing image, this reduces resource consumption when images are not being taken
// Particulary when a high-resolution camera is used occasionally
camera->setCameraTypeEnabled(image_type, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rajat2004 Hi Rajat. Thanks for your hard work on this pull request. I've been looking at this issue for a little, and so far, after commenting out this line, everything works pretty much perfectly (please verify this, I made a few other modifications so it's possible I made a change somewhere else). I ran it twice for around 50 minutes each without a single crash. My guess is this line is causing a race condition somewhere. Maybe it needs to be run on a different thread? Please let me know if that change also works for you.

Best,
Tom

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thanks for testing and figuring out the problems! I'll also try it out, if it works out then can be moved into a separate API call which the user calls the disable cameras when not needed

@rajat2004
Copy link
Contributor Author

Here's a Linux Blocks binary with the suggested fix by @cthoma20-arc - https://drive.google.com/file/d/1sK-S0CX6cqGtuMeQLqz2OhAVVg6dZAq1/view?usp=sharing
I've added the commit at faster_img_cap_test branch, getting that PR back in sync with this just seems too much painful and not worth it, probably will open a new PR itself later to replace this one (again 😅 ) since comments and all are getting longer and longer
Someone trying it out and maybe even creating a Windows binary would be great. Currently, the Azure pipelines doesn't publish the packaged Ubuntu & Win binaries anywhere, that would be a great help, since packaging takes a lot of time, especially on a laptop, plus pipelines does it faster :)

Copy link
Contributor

@cthoma20-arc cthoma20-arc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an awesome pull request, thanks again for fixing this issue 😃. I have a few more suggestions. I hope they will be useful.

Cheers,
Tom

class BufferCollection
{
public:
BufferCollection(size_t size) : Size(size) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should probably be a destructor defined for this class to avoid memory leaks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very sure about this, will need to think more and check if memory leak is happening
If destructor is defined, then copy constructor, assignment might also be required, atleast from what I understand
Any pointers, suggestions and discussions on this would be great!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please correct me if I'm wrong, but I believe a memory leak will occur since we are allocating Buffers using new but the buffers are never deleted. We make unique_ptrs using the allocated buffers, but we use a custom deleter so they aren't deleted. This isn't really a problem at the moment since a single static BufferPool is being used, but it could be an issue in the future if someone uses more BufferPool objects. The destructor should probably delete the pointers in AvailableBuffers so that that memory is freed. I think it would probably make sense to delete the copy constructor and assignment operator, since it doesn't really make sense to copy this kind of object.
Thanks again :)

params_[i]->render_component->CaptureSceneDeferred();
}
UAirBlueprintLib::RunCommandOnGameThread([this]() {
fast_cap_done_ = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this line be moved outside RunCommandOnGameThread, since the condition is checked later in the current thread?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, done, see rajat2004@901bd01

//Try to wait just long enough for the render thread to finish the capture.
//Start with a long wait, then check for completion more frequently.
//TODO: Optimize these numbers.
for (int best_guess_cap_time_microseconds = 500; !fast_cap_done_; best_guess_cap_time_microseconds = 200)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to use a condition variable and a mutex here to block until the rendering is done instead of polling fast_cap_done_?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to mutex, condition_variable, see rajat2004@901bd01
Didn't notice any major difference, not expected also

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Thank you

@rajat2004
Copy link
Contributor Author

Sorry for the late reply, I think I'll mostly open a new PR with the other branch, there are still major points which need to be fixed, but can be discussed on that PR
All the magic was done by @ironclownfish & @madratman, thanks a lot! I'm just putting on some fixes, etc on top :)

@rajat2004 rajat2004 mentioned this pull request Sep 13, 2020
5 tasks
@rajat2004
Copy link
Contributor Author

Opened #3018 which replaces this, have added the major problems right now in the description there, any testing, reviews would be great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants