[graphite] Revise UploadTask to allow creation from one UploadInstance

This allows us to create one-off UploadTasks to submit to the Recorder,
e.g. for makeTextureImage().

Also renames UploadCommand to UploadInstance to avoid confusion with
addCommand() method.

Bug: skia:12845
Change-Id: I6cad6f6df6406d1d790ecf6297996fb7ab376f54
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/521362
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2022-03-16 11:04:35 -04:00 committed by SkCQ
parent 56ec512c78
commit 03044243cc
3 changed files with 88 additions and 38 deletions

View File

@ -178,7 +178,7 @@ sk_sp<Task> DrawContext::snapRenderPassTask(Recorder* recorder,
}
sk_sp<Task> DrawContext::snapUploadTask(Recorder* recorder) {
if (!fPendingUploads) {
if (!fPendingUploads || fPendingUploads->size() == 0) {
return nullptr;
}

View File

@ -20,24 +20,12 @@
namespace skgpu {
void UploadCommand::addCommand(ResourceProvider* resourceProvider,
CommandBuffer* commandBuffer) const {
if (!fTextureProxy) {
SKGPU_LOG_E("No texture proxy specified for UploadTask");
return;
}
if (!fTextureProxy->instantiate(resourceProvider)) {
SKGPU_LOG_E("Could not instantiate texture proxy for UploadTask!");
return;
}
commandBuffer->copyBufferToTexture(std::move(fBuffer),
fTextureProxy->refTexture(),
fCopyData.data(),
fCopyData.size());
}
//---------------------------------------------------------------------------
UploadInstance::UploadInstance(sk_sp<Buffer> buffer,
sk_sp<TextureProxy> textureProxy,
std::vector<BufferTextureCopyData> copyData)
: fBuffer(buffer)
, fTextureProxy(textureProxy)
, fCopyData(copyData) {}
size_t compute_combined_buffer_size(int mipLevelCount,
size_t bytesPerPixel,
@ -68,11 +56,11 @@ size_t compute_combined_buffer_size(int mipLevelCount,
return combinedBufferSize;
}
bool UploadList::appendUpload(Recorder* recorder,
sk_sp<TextureProxy> textureProxy,
SkColorType dataColorType,
const std::vector<MipLevel>& levels,
const SkIRect& dstRect) {
UploadInstance UploadInstance::Make(Recorder* recorder,
sk_sp<TextureProxy> textureProxy,
SkColorType dataColorType,
const std::vector<MipLevel>& levels,
const SkIRect& dstRect) {
const Caps* caps = recorder->priv().caps();
SkASSERT(caps->isTexturable(textureProxy->textureInfo()));
@ -85,20 +73,20 @@ bool UploadList::appendUpload(Recorder* recorder,
SkASSERT(mipLevelCount == 1 || mipLevelCount == textureProxy->textureInfo().numMipLevels());
if (dstRect.isEmpty()) {
return false;
return {};
}
SkASSERT(caps->areColorTypeAndTextureInfoCompatible(dataColorType,
textureProxy->textureInfo()));
if (mipLevelCount == 1 && !levels[0].fPixels) {
return true; // no data to upload
return {}; // no data to upload
}
for (unsigned int i = 0; i < mipLevelCount; ++i) {
// We do not allow any gaps in the mip data
if (!levels[i].fPixels) {
return false;
return {};
}
}
@ -118,7 +106,7 @@ bool UploadList::appendUpload(Recorder* recorder,
std::vector<BufferTextureCopyData> copyData(mipLevelCount);
if (!buffer) {
return false;
return {};
}
char* bufferData = (char*) buffer->map(); // TODO: get from staging buffer instead
size_t baseOffset = 0;
@ -149,25 +137,69 @@ bool UploadList::appendUpload(Recorder* recorder,
buffer->unmap();
fCommands.push_back({std::move(buffer), std::move(textureProxy), std::move(copyData)});
return {std::move(buffer), std::move(textureProxy), std::move(copyData)};
}
void UploadInstance::addCommand(ResourceProvider* resourceProvider,
CommandBuffer* commandBuffer) const {
if (!fTextureProxy) {
SKGPU_LOG_E("No texture proxy specified for UploadTask");
return;
}
if (!fTextureProxy->instantiate(resourceProvider)) {
SKGPU_LOG_E("Could not instantiate texture proxy for UploadTask!");
return;
}
commandBuffer->copyBufferToTexture(std::move(fBuffer),
fTextureProxy->refTexture(),
fCopyData.data(),
fCopyData.size());
}
//---------------------------------------------------------------------------
bool UploadList::appendUpload(Recorder* recorder,
sk_sp<TextureProxy> textureProxy,
SkColorType dataColorType,
const std::vector<MipLevel>& levels,
const SkIRect& dstRect) {
UploadInstance instance = UploadInstance::Make(recorder, textureProxy, dataColorType,
levels, dstRect);
if (!instance.isValid()) {
return false;
}
fInstances.push_back(instance);
return true;
}
//---------------------------------------------------------------------------
sk_sp<UploadTask> UploadTask::Make(UploadList* uploadList) {
return sk_sp<UploadTask>(new UploadTask(std::move(uploadList->fCommands)));
SkASSERT(uploadList && uploadList->fInstances.size() > 0);
return sk_sp<UploadTask>(new UploadTask(std::move(uploadList->fInstances)));
}
UploadTask::UploadTask(std::vector<UploadCommand> commands) : fCommands(std::move(commands)) {}
sk_sp<UploadTask> UploadTask::Make(const UploadInstance& instance) {
if (!instance.isValid()) {
return nullptr;
}
return sk_sp<UploadTask>(new UploadTask(instance));
}
UploadTask::UploadTask(std::vector<UploadInstance> instances) : fInstances(std::move(instances)) {}
UploadTask::UploadTask(const UploadInstance& instance) {
fInstances.push_back(instance);
}
UploadTask::~UploadTask() {}
void UploadTask::addCommands(ResourceProvider* resourceProvider,
CommandBuffer* commandBuffer) {
for (unsigned int i = 0; i < fCommands.size(); ++i) {
fCommands[i].addCommand(resourceProvider, commandBuffer);
for (unsigned int i = 0; i < fInstances.size(); ++i) {
fInstances[i].addCommand(resourceProvider, commandBuffer);
}
}

View File

@ -31,12 +31,26 @@ struct MipLevel {
};
/**
* An UploadCommand represents a single set of uploads from a buffer to texture that
* An UploadInstance represents a single set of uploads from a buffer to texture that
* can be processed in a single command.
*/
struct UploadCommand {
class UploadInstance {
public:
static UploadInstance Make(Recorder*,
sk_sp<TextureProxy> targetProxy,
SkColorType colorType,
const std::vector<MipLevel>& levels,
const SkIRect& dstRect);
bool isValid() const { return fBuffer != nullptr; }
// Adds upload command to the given CommandBuffer
void addCommand(ResourceProvider*, CommandBuffer*) const;
private:
UploadInstance() {}
UploadInstance(sk_sp<Buffer>, sk_sp<TextureProxy>, std::vector<BufferTextureCopyData>);
sk_sp<Buffer> fBuffer;
sk_sp<TextureProxy> fTextureProxy;
std::vector<BufferTextureCopyData> fCopyData;
@ -60,10 +74,12 @@ public:
const std::vector<MipLevel>& levels,
const SkIRect& dstRect);
int size() { return fInstances.size(); }
private:
friend class UploadTask;
std::vector<UploadCommand> fCommands;
std::vector<UploadInstance> fInstances;
};
/*
@ -75,15 +91,17 @@ private:
class UploadTask final : public Task {
public:
static sk_sp<UploadTask> Make(UploadList*);
static sk_sp<UploadTask> Make(const UploadInstance&);
~UploadTask() override;
void addCommands(ResourceProvider*, CommandBuffer*) override;
private:
UploadTask(std::vector<UploadCommand>);
UploadTask(std::vector<UploadInstance>);
UploadTask(const UploadInstance&);
std::vector<UploadCommand> fCommands;
std::vector<UploadInstance> fInstances;
};
} // namespace skgpu