mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Add sync and async texture and buffer readback APIs.
- Add imagedata = love.graphics.readbackTexture(texture, [slice, mipmap, x, y, w, h, [dest, destx, desty]]). - Add readback = love.graphics.readbackTextureAsync(texture, [slice, mipmap, x, y, w, h, [dest, destx, desty]]). - Add bytedata = love.graphics.readbackBuffer(buffer, [offset, size, [dest, destoffset]]). - Add readback = ove.graphics.readbackBufferAsync(buffer, [offset, size, [dest, destoffset]]). - Deprecate Texture:newImageData. The async variants return a new GraphicsReadback object. It has the following methods: - isComplete() - hasError() - wait() - getBufferData() - getImageData() - update() (called automatically every frame by love, not normally needed). Support notes: - readbackBuffer and readbackBufferAsync require buffer copying support. - readbackTexture with a render target (canvas) is always supported. readbackTexture with a non-render-target requires copy-texture-to-buffer support. - readbackTextureAsync with a render target requires copy-render-target-to-buffer support. readbackTextureAsync with a non-render-target requires copy-texture-to-buffer support.
This commit is contained in:
@@ -235,6 +235,7 @@ Graphics::~Graphics()
|
||||
for (int i = 0; i < (int) SHADERSTAGE_MAX_ENUM; i++)
|
||||
cachedShaderStages[i].clear();
|
||||
|
||||
pendingReadbacks.clear();
|
||||
clearTemporaryResources();
|
||||
|
||||
Shader::deinitialize();
|
||||
@@ -434,6 +435,46 @@ love::graphics::Text *Graphics::newText(graphics::Font *font, const std::vector<
|
||||
return new Text(font, text);
|
||||
}
|
||||
|
||||
love::data::ByteData *Graphics::readbackBuffer(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset)
|
||||
{
|
||||
StrongRef<GraphicsReadback> readback;
|
||||
readback.set(newReadbackInternal(READBACK_IMMEDIATE, buffer, offset, size, dest, destoffset), Acquire::NORETAIN);
|
||||
|
||||
auto data = readback->getBufferData();
|
||||
if (data == nullptr)
|
||||
throw love::Exception("love.graphics.readbackBuffer failed.");
|
||||
|
||||
data->retain();
|
||||
return data;
|
||||
}
|
||||
|
||||
GraphicsReadback *Graphics::readbackBufferAsync(Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset)
|
||||
{
|
||||
auto readback = newReadbackInternal(READBACK_ASYNC, buffer, offset, size, dest, destoffset);
|
||||
pendingReadbacks.push_back(readback);
|
||||
return readback;
|
||||
}
|
||||
|
||||
image::ImageData *Graphics::readbackTexture(Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty)
|
||||
{
|
||||
StrongRef<GraphicsReadback> readback;
|
||||
readback.set(newReadbackInternal(READBACK_IMMEDIATE, texture, slice, mipmap, rect, dest, destx, desty), Acquire::NORETAIN);
|
||||
|
||||
auto imagedata = readback->getImageData();
|
||||
if (imagedata == nullptr)
|
||||
throw love::Exception("love.graphics.readbackTexture failed.");
|
||||
|
||||
imagedata->retain();
|
||||
return imagedata;
|
||||
}
|
||||
|
||||
GraphicsReadback *Graphics::readbackTextureAsync(Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty)
|
||||
{
|
||||
auto readback = newReadbackInternal(READBACK_ASYNC, texture, slice, mipmap, rect, dest, destx, desty);
|
||||
pendingReadbacks.push_back(readback);
|
||||
return readback;
|
||||
}
|
||||
|
||||
void Graphics::cleanupCachedShaderStage(ShaderStageType type, const std::string &hashkey)
|
||||
{
|
||||
cachedShaderStages[type].erase(hashkey);
|
||||
@@ -1120,6 +1161,20 @@ void Graphics::clearTemporaryResources()
|
||||
temporaryBuffers.clear();
|
||||
temporaryTextures.clear();
|
||||
}
|
||||
|
||||
void Graphics::updatePendingReadbacks()
|
||||
{
|
||||
for (int i = (int)pendingReadbacks.size() - 1; i >= 0; i--)
|
||||
{
|
||||
pendingReadbacks[i]->update();
|
||||
if (pendingReadbacks[i]->isComplete())
|
||||
{
|
||||
pendingReadbacks[i] = pendingReadbacks.back();
|
||||
pendingReadbacks.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::intersectScissor(const Rect &rect)
|
||||
{
|
||||
Rect currect = states.back().scissorRect;
|
||||
|
||||
Reference in New Issue
Block a user