mirror of
https://github.com/u0u0/Cocos2d-Lua-Community.git
synced 2026-05-07 06:07:25 +08:00
metal改同步等待gpu渲染,异步和上层配合有坑。同时解决RenderTexture在metal后端随机崩溃的bug.
This commit is contained in:
@@ -637,9 +637,18 @@ void RenderTexture::end()
|
||||
CCASSERT(nullptr != director, "Director is null when setting matrix stack");
|
||||
|
||||
Renderer *renderer = director->getRenderer();
|
||||
// render may call from touch event callback, and it not in Director drawScene circle.
|
||||
// need beginFrame for metal render backend, or render will crash
|
||||
bool isInitFramed = renderer->isBeginFrame();
|
||||
if (!isInitFramed) {
|
||||
renderer->beginFrame();
|
||||
}
|
||||
renderer->addCommand(&_endCommand);
|
||||
renderer->popGroup();
|
||||
renderer->render();
|
||||
if (!isInitFramed) {
|
||||
renderer->endFrame();
|
||||
}
|
||||
|
||||
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||
|
||||
@@ -343,10 +343,12 @@ void Renderer::render()
|
||||
void Renderer::beginFrame()
|
||||
{
|
||||
_commandBuffer->beginFrame();
|
||||
_isBeginFrame = true;
|
||||
}
|
||||
|
||||
void Renderer::endFrame()
|
||||
{
|
||||
_isBeginFrame = false;
|
||||
_commandBuffer->endFrame();
|
||||
|
||||
#ifdef CC_USE_METAL
|
||||
|
||||
@@ -400,6 +400,10 @@ public:
|
||||
/** returns whether or not a rectangle is visible or not */
|
||||
bool checkVisibility(const Mat4& transform, const Size& size);
|
||||
|
||||
bool isBeginFrame() { return _isBeginFrame;};
|
||||
void beginFrame(); /// Indicate the begining of a frame
|
||||
void endFrame(); /// Finish a frame.
|
||||
|
||||
protected:
|
||||
friend class Director;
|
||||
friend class GroupCommand;
|
||||
@@ -447,9 +451,6 @@ protected:
|
||||
void drawMeshCommand(RenderCommand* command);
|
||||
void captureScreen(RenderCommand* command);
|
||||
|
||||
void beginFrame(); /// Indicate the begining of a frame
|
||||
void endFrame(); /// Finish a frame.
|
||||
|
||||
///Draw the previews queued triangles and flush previous context
|
||||
void flush();
|
||||
|
||||
@@ -527,6 +528,7 @@ protected:
|
||||
//the flag for checking whether renderer is rendering
|
||||
bool _isRendering = false;
|
||||
bool _isDepthTestFor2D = false;
|
||||
bool _isBeginFrame = false;
|
||||
|
||||
GroupCommandManager* _groupCommandManager = nullptr;
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ private:
|
||||
unsigned int _renderTargetWidth = 0;
|
||||
unsigned int _renderTargetHeight = 0;
|
||||
|
||||
dispatch_semaphore_t _frameBoundarySemaphore;
|
||||
RenderPassDescriptor _prevRenderPassDescriptor;
|
||||
NSAutoreleasePool* _autoReleasePool = nil;
|
||||
};
|
||||
|
||||
@@ -213,19 +213,16 @@ namespace
|
||||
|
||||
CommandBufferMTL::CommandBufferMTL(DeviceMTL* deviceMTL)
|
||||
: _mtlCommandQueue(deviceMTL->getMTLCommandQueue())
|
||||
, _frameBoundarySemaphore(dispatch_semaphore_create(MAX_INFLIGHT_BUFFER))
|
||||
{
|
||||
}
|
||||
|
||||
CommandBufferMTL::~CommandBufferMTL()
|
||||
{
|
||||
dispatch_semaphore_signal(_frameBoundarySemaphore);
|
||||
}
|
||||
|
||||
void CommandBufferMTL::beginFrame()
|
||||
{
|
||||
_autoReleasePool = [[NSAutoreleasePool alloc] init];
|
||||
dispatch_semaphore_wait(_frameBoundarySemaphore, DISPATCH_TIME_FOREVER);
|
||||
|
||||
_mtlCommandBuffer = [_mtlCommandQueue commandBuffer];
|
||||
[_mtlCommandBuffer enqueue];
|
||||
@@ -362,13 +359,8 @@ void CommandBufferMTL::endFrame()
|
||||
|
||||
[_mtlCommandBuffer presentDrawable:DeviceMTL::getCurrentDrawable()];
|
||||
_drawableTexture = DeviceMTL::getCurrentDrawable().texture;
|
||||
[_mtlCommandBuffer addCompletedHandler:^(id<MTLCommandBuffer> commandBuffer) {
|
||||
// GPU work is complete
|
||||
// Signal the semaphore to start the CPU work
|
||||
dispatch_semaphore_signal(_frameBoundarySemaphore);
|
||||
}];
|
||||
|
||||
[_mtlCommandBuffer commit];
|
||||
[_mtlCommandBuffer waitUntilCompleted];
|
||||
[_mtlCommandBuffer release];
|
||||
DeviceMTL::resetCurrentDrawable();
|
||||
[_autoReleasePool drain];
|
||||
|
||||
@@ -111,12 +111,12 @@ int main(int argc, char *argv[])
|
||||
// create after GLView inited
|
||||
ConsoleWindowController *consoleController = [[ConsoleWindowController alloc] initWithWindowNibName:@"ConsoleWindow"];
|
||||
[consoleController.window orderFrontRegardless];
|
||||
#endif
|
||||
|
||||
std::string logPath = cmd->getLogPath();
|
||||
if (logPath.size() > 0) {
|
||||
[consoleController openLogToFile:logPath.c_str()];
|
||||
}
|
||||
#endif
|
||||
|
||||
setupMenu();// after GLView inited
|
||||
|
||||
|
||||
Reference in New Issue
Block a user