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/semaphore.h>
|
||||||
#include <mach/sync_policy.h>
|
#include <mach/sync_policy.h>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#import "DisplayViewCALayer.h"
|
#import "DisplayViewCALayer.h"
|
||||||
#import "../cocoa_GPU.h"
|
#import "../cocoa_GPU.h"
|
||||||
#import "../cocoa_util.h"
|
#import "../cocoa_util.h"
|
||||||
|
@ -269,7 +271,7 @@ typedef DisplayViewShaderProperties DisplayViewShaderProperties;
|
||||||
MacDisplayLayeredView *_cdv;
|
MacDisplayLayeredView *_cdv;
|
||||||
MacMetalDisplayPresenterObject *presenterObject;
|
MacMetalDisplayPresenterObject *presenterObject;
|
||||||
dispatch_semaphore_t _semDrawable;
|
dispatch_semaphore_t _semDrawable;
|
||||||
id<CAMetalDrawable> _currentDrawable;
|
std::queue< id<CAMetalDrawable> > *_drawableQueue;
|
||||||
id<CAMetalDrawable> layerDrawable0;
|
id<CAMetalDrawable> layerDrawable0;
|
||||||
id<CAMetalDrawable> layerDrawable1;
|
id<CAMetalDrawable> layerDrawable1;
|
||||||
id<CAMetalDrawable> layerDrawable2;
|
id<CAMetalDrawable> layerDrawable2;
|
||||||
|
|
|
@ -2261,7 +2261,7 @@
|
||||||
|
|
||||||
_cdv = NULL;
|
_cdv = NULL;
|
||||||
_semDrawable = dispatch_semaphore_create(3);
|
_semDrawable = dispatch_semaphore_create(3);
|
||||||
_currentDrawable = nil;
|
_drawableQueue = new std::queue< id<CAMetalDrawable> >;
|
||||||
layerDrawable0 = nil;
|
layerDrawable0 = nil;
|
||||||
layerDrawable1 = nil;
|
layerDrawable1 = nil;
|
||||||
layerDrawable2 = nil;
|
layerDrawable2 = nil;
|
||||||
|
@ -2290,6 +2290,8 @@
|
||||||
[self setLayerDrawable2:nil];
|
[self setLayerDrawable2:nil];
|
||||||
dispatch_release(_semDrawable);
|
dispatch_release(_semDrawable);
|
||||||
|
|
||||||
|
delete _drawableQueue;
|
||||||
|
|
||||||
[_displayTexturePair.main release];
|
[_displayTexturePair.main release];
|
||||||
[_displayTexturePair.touch release];
|
[_displayTexturePair.touch release];
|
||||||
|
|
||||||
|
@ -2312,7 +2314,6 @@
|
||||||
id<CAMetalDrawable> drawable = [self nextDrawable];
|
id<CAMetalDrawable> drawable = [self nextDrawable];
|
||||||
if (drawable == nil)
|
if (drawable == nil)
|
||||||
{
|
{
|
||||||
_currentDrawable = nil;
|
|
||||||
dispatch_semaphore_signal(_semDrawable);
|
dispatch_semaphore_signal(_semDrawable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2332,6 +2333,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_drawableQueue->push(drawable);
|
||||||
|
|
||||||
id<MTLTexture> texDrawable = [drawable texture];
|
id<MTLTexture> texDrawable = [drawable texture];
|
||||||
[[presenterObject colorAttachment0Desc] setTexture:texDrawable];
|
[[presenterObject colorAttachment0Desc] setTexture:texDrawable];
|
||||||
|
|
||||||
|
@ -2363,19 +2366,19 @@
|
||||||
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
|
[cb addCompletedHandler:^(id<MTLCommandBuffer> block) {
|
||||||
[presenterObject renderFinishAtIndex:mrfi.renderIndex];
|
[presenterObject renderFinishAtIndex:mrfi.renderIndex];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
_currentDrawable = drawable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) presentDrawableWithCommandBuffer:(id<MTLCommandBuffer>)cb outputTime:(uint64_t)outputTime
|
- (void) presentDrawableWithCommandBuffer:(id<MTLCommandBuffer>)cb outputTime:(uint64_t)outputTime
|
||||||
{
|
{
|
||||||
id<CAMetalDrawable> drawable = _currentDrawable;
|
if (_drawableQueue->empty())
|
||||||
if (drawable == nil)
|
|
||||||
{
|
{
|
||||||
printf("Metal: No drawable was assigned!\n");
|
printf("Metal: No drawable was assigned!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id<CAMetalDrawable> drawable = _drawableQueue->front();
|
||||||
|
_drawableQueue->pop();
|
||||||
|
|
||||||
// Apple's documentation might seem to suggest that [MTLCommandBuffer presentDrawable:atTime:]
|
// Apple's documentation might seem to suggest that [MTLCommandBuffer presentDrawable:atTime:]
|
||||||
// and [MTLDrawable presentAtTime:] inside of a [MTLCommandBuffer addScheduledHandler:] block
|
// and [MTLDrawable presentAtTime:] inside of a [MTLCommandBuffer addScheduledHandler:] block
|
||||||
// are equivalent. However, much testing has shown that this is NOT the case.
|
// are equivalent. However, much testing has shown that this is NOT the case.
|
||||||
|
|
Loading…
Reference in New Issue