How to render 2 images independently in metal











up vote
0
down vote

favorite












my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0 so that I can see my back image also.my draw method looks like below.



    public func draw(in: MTKView) {

autoreleasepool {
guard let texture = texture else {
print("Error : camera stream failed to create texture")
return
}
guard let device = self.device else {
print("Error : Metal Device is nil")
return
}
guard let commandBuffer = commandQueue?.makeCommandBuffer() else {
print("Error : Command encoder is nil")
return
}


// resposible to create metal camera effect in camera raw image and output will be written to
// internalTexture, if success, internal texture will be present to the screen using encoder

self.createMetalEffect(texture, inputCommandBuffer: commandBuffer)

guard let commandGifBuffer = commandQueue?.makeCommandBuffer() else{
print("Error : Command encoder is nil")
return
}

// rendering the effect output texture (writen to internalTexture via kernel) on screen
// so the self.internalTexture must not be nil!
render(texture: self.internalTexture!, withCommandBuffer: commandBuffer, device: device)

// for loading gif here
if isGifEnable{
if count == self.imageArray.count - 1{
count = 0
}else{
count += 1
}
if let giftexture = self.loadImageFrame(img: self.imageArray[count]){
self.createGifMetalEffect(giftexture, inputCommandBuffer: commandGifBuffer)
render(texture: self.gifInternalTexture!, withCommandBuffer: commandGifBuffer, device: device)
}
}

/// ------------------------- end gif loading ------------------------------


}
}


and for presenting images my render method looks like this.



        private func render(texture: MTLTexture,
withCommandBuffer commandBuffer: MTLCommandBuffer,
device: MTLDevice) {


guard let renderPassDescriptor = metalView.currentRenderPassDescriptor else {
print("Error : Render pass descriptor is nil")
return
}
guard let drawable = metalView.currentDrawable else {
print("Error : drawable from metal view is nil")
return
}
guard let pipelineState = self.pipelineState else {
print("Error : pipelineState is nil")
return
}
// guard let animation = self.animationDescriptor else {
// print("Error : animation is nil")
// return
// }
guard let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
print("Error : Fail to create screen render encoder from command buffer!")
return
}
encoder.pushDebugGroup("RenderFrame")
encoder.setRenderPipelineState(pipelineState)
encoder.setFragmentTexture(texture, index: 0)
encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0,
vertexCount: 4, instanceCount: 1)

encoder.popDebugGroup()
encoder.endEncoding()

commandBuffer.present(drawable)

commandBuffer.commit()
commandBuffer.waitUntilCompleted()
self.metalTexture = texture

// self.metalWriteQueue.async {
// self.writeTexture(texture)
// }

}


I have renderGif method also which looks same as render method but with different parameter name self.gifInternalTexture! and commandGifBuffer.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is



should not be called after already presenting this drawable. Get a nextDrawable instead.


maybe because it already present currentdrawable in render function. so how can I render tow image independently and show one under the another?? What should be my architecture?










share|improve this question
























  • you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
    – E.Coms
    Nov 7 at 18:24















up vote
0
down vote

favorite












my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0 so that I can see my back image also.my draw method looks like below.



    public func draw(in: MTKView) {

autoreleasepool {
guard let texture = texture else {
print("Error : camera stream failed to create texture")
return
}
guard let device = self.device else {
print("Error : Metal Device is nil")
return
}
guard let commandBuffer = commandQueue?.makeCommandBuffer() else {
print("Error : Command encoder is nil")
return
}


// resposible to create metal camera effect in camera raw image and output will be written to
// internalTexture, if success, internal texture will be present to the screen using encoder

self.createMetalEffect(texture, inputCommandBuffer: commandBuffer)

guard let commandGifBuffer = commandQueue?.makeCommandBuffer() else{
print("Error : Command encoder is nil")
return
}

// rendering the effect output texture (writen to internalTexture via kernel) on screen
// so the self.internalTexture must not be nil!
render(texture: self.internalTexture!, withCommandBuffer: commandBuffer, device: device)

// for loading gif here
if isGifEnable{
if count == self.imageArray.count - 1{
count = 0
}else{
count += 1
}
if let giftexture = self.loadImageFrame(img: self.imageArray[count]){
self.createGifMetalEffect(giftexture, inputCommandBuffer: commandGifBuffer)
render(texture: self.gifInternalTexture!, withCommandBuffer: commandGifBuffer, device: device)
}
}

/// ------------------------- end gif loading ------------------------------


}
}


and for presenting images my render method looks like this.



        private func render(texture: MTLTexture,
withCommandBuffer commandBuffer: MTLCommandBuffer,
device: MTLDevice) {


guard let renderPassDescriptor = metalView.currentRenderPassDescriptor else {
print("Error : Render pass descriptor is nil")
return
}
guard let drawable = metalView.currentDrawable else {
print("Error : drawable from metal view is nil")
return
}
guard let pipelineState = self.pipelineState else {
print("Error : pipelineState is nil")
return
}
// guard let animation = self.animationDescriptor else {
// print("Error : animation is nil")
// return
// }
guard let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
print("Error : Fail to create screen render encoder from command buffer!")
return
}
encoder.pushDebugGroup("RenderFrame")
encoder.setRenderPipelineState(pipelineState)
encoder.setFragmentTexture(texture, index: 0)
encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0,
vertexCount: 4, instanceCount: 1)

encoder.popDebugGroup()
encoder.endEncoding()

commandBuffer.present(drawable)

commandBuffer.commit()
commandBuffer.waitUntilCompleted()
self.metalTexture = texture

// self.metalWriteQueue.async {
// self.writeTexture(texture)
// }

}


I have renderGif method also which looks same as render method but with different parameter name self.gifInternalTexture! and commandGifBuffer.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is



should not be called after already presenting this drawable. Get a nextDrawable instead.


maybe because it already present currentdrawable in render function. so how can I render tow image independently and show one under the another?? What should be my architecture?










share|improve this question
























  • you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
    – E.Coms
    Nov 7 at 18:24













up vote
0
down vote

favorite









up vote
0
down vote

favorite











my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0 so that I can see my back image also.my draw method looks like below.



    public func draw(in: MTKView) {

autoreleasepool {
guard let texture = texture else {
print("Error : camera stream failed to create texture")
return
}
guard let device = self.device else {
print("Error : Metal Device is nil")
return
}
guard let commandBuffer = commandQueue?.makeCommandBuffer() else {
print("Error : Command encoder is nil")
return
}


// resposible to create metal camera effect in camera raw image and output will be written to
// internalTexture, if success, internal texture will be present to the screen using encoder

self.createMetalEffect(texture, inputCommandBuffer: commandBuffer)

guard let commandGifBuffer = commandQueue?.makeCommandBuffer() else{
print("Error : Command encoder is nil")
return
}

// rendering the effect output texture (writen to internalTexture via kernel) on screen
// so the self.internalTexture must not be nil!
render(texture: self.internalTexture!, withCommandBuffer: commandBuffer, device: device)

// for loading gif here
if isGifEnable{
if count == self.imageArray.count - 1{
count = 0
}else{
count += 1
}
if let giftexture = self.loadImageFrame(img: self.imageArray[count]){
self.createGifMetalEffect(giftexture, inputCommandBuffer: commandGifBuffer)
render(texture: self.gifInternalTexture!, withCommandBuffer: commandGifBuffer, device: device)
}
}

/// ------------------------- end gif loading ------------------------------


}
}


and for presenting images my render method looks like this.



        private func render(texture: MTLTexture,
withCommandBuffer commandBuffer: MTLCommandBuffer,
device: MTLDevice) {


guard let renderPassDescriptor = metalView.currentRenderPassDescriptor else {
print("Error : Render pass descriptor is nil")
return
}
guard let drawable = metalView.currentDrawable else {
print("Error : drawable from metal view is nil")
return
}
guard let pipelineState = self.pipelineState else {
print("Error : pipelineState is nil")
return
}
// guard let animation = self.animationDescriptor else {
// print("Error : animation is nil")
// return
// }
guard let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
print("Error : Fail to create screen render encoder from command buffer!")
return
}
encoder.pushDebugGroup("RenderFrame")
encoder.setRenderPipelineState(pipelineState)
encoder.setFragmentTexture(texture, index: 0)
encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0,
vertexCount: 4, instanceCount: 1)

encoder.popDebugGroup()
encoder.endEncoding()

commandBuffer.present(drawable)

commandBuffer.commit()
commandBuffer.waitUntilCompleted()
self.metalTexture = texture

// self.metalWriteQueue.async {
// self.writeTexture(texture)
// }

}


I have renderGif method also which looks same as render method but with different parameter name self.gifInternalTexture! and commandGifBuffer.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is



should not be called after already presenting this drawable. Get a nextDrawable instead.


maybe because it already present currentdrawable in render function. so how can I render tow image independently and show one under the another?? What should be my architecture?










share|improve this question















my target is to render 2 image spontaneously.First image or texture is my camera image which comes from live video and for second one I want to load image from gif where some position of the gif has alpha = 0 so that I can see my back image also.my draw method looks like below.



    public func draw(in: MTKView) {

autoreleasepool {
guard let texture = texture else {
print("Error : camera stream failed to create texture")
return
}
guard let device = self.device else {
print("Error : Metal Device is nil")
return
}
guard let commandBuffer = commandQueue?.makeCommandBuffer() else {
print("Error : Command encoder is nil")
return
}


// resposible to create metal camera effect in camera raw image and output will be written to
// internalTexture, if success, internal texture will be present to the screen using encoder

self.createMetalEffect(texture, inputCommandBuffer: commandBuffer)

guard let commandGifBuffer = commandQueue?.makeCommandBuffer() else{
print("Error : Command encoder is nil")
return
}

// rendering the effect output texture (writen to internalTexture via kernel) on screen
// so the self.internalTexture must not be nil!
render(texture: self.internalTexture!, withCommandBuffer: commandBuffer, device: device)

// for loading gif here
if isGifEnable{
if count == self.imageArray.count - 1{
count = 0
}else{
count += 1
}
if let giftexture = self.loadImageFrame(img: self.imageArray[count]){
self.createGifMetalEffect(giftexture, inputCommandBuffer: commandGifBuffer)
render(texture: self.gifInternalTexture!, withCommandBuffer: commandGifBuffer, device: device)
}
}

/// ------------------------- end gif loading ------------------------------


}
}


and for presenting images my render method looks like this.



        private func render(texture: MTLTexture,
withCommandBuffer commandBuffer: MTLCommandBuffer,
device: MTLDevice) {


guard let renderPassDescriptor = metalView.currentRenderPassDescriptor else {
print("Error : Render pass descriptor is nil")
return
}
guard let drawable = metalView.currentDrawable else {
print("Error : drawable from metal view is nil")
return
}
guard let pipelineState = self.pipelineState else {
print("Error : pipelineState is nil")
return
}
// guard let animation = self.animationDescriptor else {
// print("Error : animation is nil")
// return
// }
guard let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
print("Error : Fail to create screen render encoder from command buffer!")
return
}
encoder.pushDebugGroup("RenderFrame")
encoder.setRenderPipelineState(pipelineState)
encoder.setFragmentTexture(texture, index: 0)
encoder.drawPrimitives(type: .triangleStrip, vertexStart: 0,
vertexCount: 4, instanceCount: 1)

encoder.popDebugGroup()
encoder.endEncoding()

commandBuffer.present(drawable)

commandBuffer.commit()
commandBuffer.waitUntilCompleted()
self.metalTexture = texture

// self.metalWriteQueue.async {
// self.writeTexture(texture)
// }

}


I have renderGif method also which looks same as render method but with different parameter name self.gifInternalTexture! and commandGifBuffer.So the question is when I render my video without gif it works fine but when I apply gif which I expect to render in top are not showing and also video is frizzing maybe because of this command commandBuffer.waitUntilCompleted()
the warning message which it give is



should not be called after already presenting this drawable. Get a nextDrawable instead.


maybe because it already present currentdrawable in render function. so how can I render tow image independently and show one under the another?? What should be my architecture?







ios swift metal metalkit






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 7 at 9:30









Cœur

16.9k9102139




16.9k9102139










asked Nov 7 at 9:25









Rumy

124112




124112












  • you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
    – E.Coms
    Nov 7 at 18:24


















  • you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
    – E.Coms
    Nov 7 at 18:24
















you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24




you may try remove ` commandBuffer.waitUntilCompleted()` to see the result
– E.Coms
Nov 7 at 18:24

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53186592%2fhow-to-render-2-images-independently-in-metal%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53186592%2fhow-to-render-2-images-independently-in-metal%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()