Cocoa Port: Use a std::queue to keep track of Metal drawable ordering.
- This is probably super paranoid and completely overkill, but it makes me feel better to do this. Now there is absolute certainty that nothing can disrupt the drawable order in between rendering and presentation. Microstuttering from mis-ordered drawables can no longer happen.
This commit is contained in:
parent
32461006d9
commit
bd030db03f
|
@ -26,6 +26,8 @@
|
|||
#include <mach/semaphore.h>
|
||||
#include <mach/sync_policy.h>
|
||||
|
||||
#include <queue>
|
||||
|
||||
#import "DisplayViewCALayer.h"
|
||||
#import "../cocoa_GPU.h"
|
||||
#import "../cocoa_util.h"
|
||||
|
@ -269,7 +271,7 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties;
|
|||
MacDisplayLayeredView *_cdv;
|
||||
MacMetalDisplayPresenterObject *presenterObject;
|
||||
dispatch_semaphore_t _semDrawable;
|
||||
id<CAMetalDrawable> _currentDrawable;
|
||||
std::queue< id<CAMetalDrawable> > *_drawableQueue;
|
||||
id<CAMetalDrawable> layerDrawable0;
|
||||
id<CAMetalDrawable> layerDrawable1;
|
||||
id<CAMetalDrawable> layerDrawable2;
|
||||
|
|
|
@ -2261,7 +2261,7 @@
|
|||
|
||||
_cdv = NULL;
|
||||
_semDrawable = dispatch_semaphore_create(3);
|
||||
_currentDrawable = nil;
|
||||
_drawableQueue = new std::queue< id<CAMetalDrawable> >;
|
||||
layerDrawable0 = nil;
|
||||
layerDrawable1 = nil;
|
||||
layerDrawable2 = nil;
|
||||
|
@ -2290,6 +2290,8 @@
|
|||
[self setLayerDrawable2:nil];
|
||||
dispatch_release(_semDrawable);
|
||||
|
||||
delete _drawableQueue;
|
||||
|
||||
[_displayTexturePair.main release];
|
||||
[_displayTexturePair.touch release];
|
||||
|
||||
|
@ -2312,7 +2314,6 @@
|
|||
id<CAMetalDrawable> drawable = [self nextDrawable];
|
||||
if (drawable == nil)
|
||||
{
|
||||
_currentDrawable = nil;
|
||||
dispatch_semaphore_signal(_semDrawable);
|
||||
return;
|
||||
}
|
||||
|
@ -2332,6 +2333,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
_drawableQueue->push(drawable);
|
||||
|
||||
id<MTLTexture> texDrawable = [drawable texture];
|
||||
[[presenterObject colorAttachment0Desc] setTexture:texDrawable];
|
||||
|
||||
|
@ -2363,19 +2366,19 @@
|
|||
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
|
||||
[presenterObject renderFinishAtIndex:mrfi.renderIndex];
|
||||
}];
|
||||
|
||||
_currentDrawable = drawable;
|
||||
}
|
||||
|
||||
- (void) presentDrawableWithCommandBuffer:(id<MTLCommandBuffer>)cb outputTime:(uint64_t)outputTime
|
||||
{
|
||||
id<CAMetalDrawable> drawable = _currentDrawable;
|
||||
if (drawable == nil)
|
||||
if (_drawableQueue->empty())
|
||||
{
|
||||
printf("Metal: No drawable was assigned!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
id<CAMetalDrawable> drawable = _drawableQueue->front();
|
||||
_drawableQueue->pop();
|
||||
|
||||
// Apple's documentation might seem to suggest that [MTLCommandBuffer presentDrawable:atTime:]
|
||||
// and [MTLDrawable presentAtTime:] inside of a [MTLCommandBuffer addScheduledHandler:] block
|
||||
// are equivalent. However, much testing has shown that this is NOT the case.
|
||||
|
|
Loading…
Reference in New Issue