mirror of https://github.com/axmolengine/axmol.git
Merge pull request #12776 from fusijie/refine_capture
CaptureScreen save in thread.
This commit is contained in:
commit
3adecedcee
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "base/CCDirector.h"
|
#include "base/CCDirector.h"
|
||||||
|
#include "base/CCAsyncTaskPool.h"
|
||||||
#include "renderer/CCCustomCommand.h"
|
#include "renderer/CCCustomCommand.h"
|
||||||
#include "renderer/CCRenderer.h"
|
#include "renderer/CCRenderer.h"
|
||||||
#include "platform/CCImage.h"
|
#include "platform/CCImage.h"
|
||||||
|
@ -49,22 +50,39 @@ int ccNextPOT(int x)
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Capture screen implementation, don't use it directly.
|
* Capture screen implementation, don't use it directly.
|
||||||
*/
|
*/
|
||||||
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterCaptured, const std::string& filename)
|
||||||
{
|
{
|
||||||
|
static bool startedCapture = false;
|
||||||
|
|
||||||
|
if (startedCapture)
|
||||||
|
{
|
||||||
|
CCLOG("Screen capture is already working");
|
||||||
|
if (afterCaptured)
|
||||||
|
{
|
||||||
|
afterCaptured(false, filename);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startedCapture = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
auto glView = Director::getInstance()->getOpenGLView();
|
auto glView = Director::getInstance()->getOpenGLView();
|
||||||
auto frameSize = glView->getFrameSize();
|
auto frameSize = glView->getFrameSize();
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
|
||||||
frameSize = frameSize * glView->getFrameZoomFactor() * glView->getRetinaFactor();
|
frameSize = frameSize * glView->getFrameZoomFactor() * glView->getRetinaFactor();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int width = static_cast<int>(frameSize.width);
|
int width = static_cast<int>(frameSize.width);
|
||||||
int height = static_cast<int>(frameSize.height);
|
int height = static_cast<int>(frameSize.height);
|
||||||
|
|
||||||
bool succeed = false;
|
bool succeed = false;
|
||||||
std::string outputFile = "";
|
std::string outputFile = "";
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
|
std::shared_ptr<GLubyte> buffer(new GLubyte[width * height * 4], [](GLubyte* p){ CC_SAFE_DELETE_ARRAY(p); });
|
||||||
|
@ -72,10 +90,10 @@ void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterC
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
||||||
|
|
||||||
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
|
std::shared_ptr<GLubyte> flippedBuffer(new GLubyte[width * height * 4], [](GLubyte* p) { CC_SAFE_DELETE_ARRAY(p); });
|
||||||
if (!flippedBuffer)
|
if (!flippedBuffer)
|
||||||
{
|
{
|
||||||
|
@ -87,7 +105,7 @@ void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterC
|
||||||
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
|
memcpy(flippedBuffer.get() + (height - row - 1) * width * 4, buffer.get() + row * width * 4, width * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Image> image(new Image);
|
Image* image = new (std::nothrow) Image;
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
|
image->initWithRawData(flippedBuffer.get(), width * height * 4, width, height, 8);
|
||||||
|
@ -100,15 +118,36 @@ void onCaptureScreen(const std::function<void(bool, const std::string&)>& afterC
|
||||||
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
|
CCASSERT(filename.find("/") == std::string::npos, "The existence of a relative path is not guaranteed!");
|
||||||
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
outputFile = FileUtils::getInstance()->getWritablePath() + filename;
|
||||||
}
|
}
|
||||||
succeed = image->saveToFile(outputFile);
|
|
||||||
|
// Save image in AsyncTaskPool::TaskType::TASK_IO thread, and call afterCaptured in mainThread
|
||||||
|
static bool succeedSaveToFile = false;
|
||||||
|
std::function<void(void*)> mainThread = [afterCaptured, outputFile](void* param)
|
||||||
|
{
|
||||||
|
if (afterCaptured)
|
||||||
|
{
|
||||||
|
afterCaptured(succeedSaveToFile, outputFile);
|
||||||
|
}
|
||||||
|
startedCapture = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
AsyncTaskPool::getInstance()->enqueue(AsyncTaskPool::TaskType::TASK_IO, mainThread, (void*)NULL, [image, outputFile]()
|
||||||
|
{
|
||||||
|
succeedSaveToFile = image->saveToFile(outputFile);
|
||||||
|
delete image;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}while(0);
|
else
|
||||||
|
{
|
||||||
if (afterCaptured)
|
CCLOG("Malloc Image memory failed!");
|
||||||
{
|
if (afterCaptured)
|
||||||
afterCaptured(succeed, outputFile);
|
{
|
||||||
}
|
afterCaptured(succeed, outputFile);
|
||||||
|
}
|
||||||
|
startedCapture = false;
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Capture screen interface
|
* Capture screen interface
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue