- Problem with CAMetalLayer nextDrawable on OSX 10.11 Beta 2

Whenever I add CAMetalLayer

in NSView

, the method [CAMetalLayer nextDrawable]

will go through nil

after 3 successful ones id<CAMetalDrawable>

.

I tried two different setup methods. First, I used MTKView and used it CAMetalLayer

, it didn't work. Secondly, NSView

a new one is used and created CAMetalLayer

. It didn't work either. I was having strange problems.

I want to know if anyone else has this problem and if anyone knows a solution to solve this problem.

Additional Notes:
I don't want to use the MTKView paint system by overriding its methods (not yet). Also this is not a problem for iOS 8 and I have not tried my code with iOS 9 beta (not yet).

Update

I am redirecting my invitations to use a delegate MTKViewDelegate

. And from the delegate method drawInView

I was able to get the consistent available frameworks. However , I would still like to use the method nextDrawable

directly from CAMetalLayer

. Hope this helps someone else.

+3


source to share


3 answers


I forgot to come back to this.



It was fixed

with OSX Beta 4

. nextDrawable

works correctly and returns useful CAMetalDrawable

objects. Probably, I should have waited for the release version to be released before publishing it. I just wanted everyone else to be aware of this issue when the beta was first released.

-1


source


I had the same problem and asked WWDC Developers Metal 15 .

How it MTKView

works
: MTKView

Has a limited number of drawings (maybe 3), so when you code frames you can draw multiple links.

What are you doing . Your scene is probably pretty simple, so you can encode frames very quickly. It looks like when the CPU is 4 frames ahead of the GPU, you are asking for the next result, and since all (3) blueprints are in use, it fails.

Solution . You need to use semapthore to wait for drawable when there is no free.

Here's the code to use:



let inflightSemaphore = dispatch_semaphore_create(3)

func drawInView(view: MTKView) {

        // use semaphore to encode 3 frames ahead
        dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER)

        self.update()

        let commandBuffer = commandQueue.commandBuffer()
        let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(view.currentRenderPassDescriptor!)
        renderEncoder.drawPrimitives()


        // use completion handler to signal the semaphore when this frame is completed allowing the encoding of the next frame to proceed
        commandBuffer.addCompletedHandler{ [weak self] commandBuffer in
            if let strongSelf = self {
                dispatch_semaphore_signal(strongSelf.inflightSemaphore)
            }
            return
        }

        commandBuffer.presentDrawable(view.currentDrawable!)
        commandBuffer.commit()
    }

      

This is not documented anywhere! The only written mention of this is in the iOS project template (File -> New -> Project -> Game -> Pick Metal) in GameViewController

.

I have already completed the radar on this one (not answered yet) and it would be appreciated if you would do the same https://bugreport.apple.com

Also you can find my github repo helpful https://github.com/haawa799/RamOnMetal

+2


source


Use @autoreleasepool

for rendering in drawable.

https://forums.developer.apple.com/thread/15102

0


source







All Articles