Add GrContext api to update compressed backend textures.

Bug: chromium:1099255
Change-Id: I0c3f25ddb037e47e3b910fa89c3d8b3aa27b3114
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302265
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2020-07-13 14:57:47 -04:00 committed by Skia Commit-Bot
parent 1a0cf309cb
commit 2c180304dc
4 changed files with 127 additions and 3 deletions

View File

@ -7,6 +7,9 @@ This file includes a list of high level updates for each milestone release.
Milestone 86
------------
* Add GrContext api to update compressed backend textures.
https://review.skia.org/302265
* Add option for clients to own semaphores after wait calls.
https://review.skia.org/301216

View File

@ -647,6 +647,39 @@ public:
GrGpuFinishedProc finishedProc = nullptr,
GrGpuFinishedContext finishedContext = nullptr);
/**
* If possible, updates a backend texture filled with the provided color. If the texture is
* mipmapped, all levels of the mip chain will be updated to have the supplied color. The client
* should check the return value to see if the update was successful. The client can pass in a
* finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
* deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
* The finishedProc will always get called even if we failed to create the GrBackendTexture.
* For the Vulkan backend after a successful update the layout of the created VkImage will be:
* VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
*/
bool updateCompressedBackendTexture(const GrBackendTexture&,
const SkColor4f& color,
GrGpuFinishedProc finishedProc,
GrGpuFinishedContext finishedContext);
/**
* If possible, updates a backend texture filled with the provided raw data. The client
* should check the return value to see if the update was successful. The client can pass in a
* finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
* deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
* The finishedProc will always get called even if we failed to create the GrBackendTexture.
* If a mipMapped texture is passed in, the data for all the mipmap levels must be provided.
* Additionally, all the miplevels must be sized correctly (please see
* SkMipMap::ComputeLevelSize and ComputeLevelCount).
* For the Vulkan backend after a successful update the layout of the created VkImage will be:
* VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
*/
bool updateCompressedBackendTexture(const GrBackendTexture&,
const void* data,
size_t dataSize,
GrGpuFinishedProc finishedProc,
GrGpuFinishedContext finishedContext);
/**
* Updates the state of the GrBackendTexture/RenderTarget to have the passed in
* GrBackendSurfaceMutableState. All objects that wrap the backend surface (i.e. SkSurfaces and

View File

@ -821,6 +821,56 @@ bool GrContext::setBackendTextureState(const GrBackendTexture& backendTexture,
return fGpu->setBackendTextureState(backendTexture, state, std::move(callback));
}
bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
const SkColor4f& color,
GrGpuFinishedProc finishedProc,
GrGpuFinishedContext finishedContext) {
sk_sp<GrRefCntedCallback> finishedCallback;
if (finishedProc) {
finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
}
if (!this->asDirectContext()) {
return false;
}
if (this->abandoned()) {
return false;
}
GrGpu::BackendTextureData data(color);
return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
const void* compressedData,
size_t dataSize,
GrGpuFinishedProc finishedProc,
GrGpuFinishedContext finishedContext) {
sk_sp<GrRefCntedCallback> finishedCallback;
if (finishedProc) {
finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
}
if (!this->asDirectContext()) {
return false;
}
if (this->abandoned()) {
return false;
}
if (!compressedData) {
return false;
}
GrGpu::BackendTextureData data(compressedData, dataSize);
return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
//////////////////////////////////////////////////////////////////////////////
bool GrContext::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
const GrBackendSurfaceMutableState& state,
GrGpuFinishedProc finishedProc,

View File

@ -157,8 +157,23 @@ static void test_compressed_color_init(GrContext* context,
check_compressed_mipmaps(context, img, compression, expectedColors, mipMapped,
reporter, "colorinit");
check_readback(context, std::move(img), compression, color, reporter,
"solid readback");
check_readback(context, img, compression, color, reporter, "solid readback");
SkColor4f newColor;
newColor.fR = color.fB;
newColor.fG = color.fR;
newColor.fB = color.fG;
newColor.fA = color.fA;
bool result = context->updateCompressedBackendTexture(backendTex, newColor, nullptr, nullptr);
// Since we were able to create the compressed texture we should be able to update it.
REPORTER_ASSERT(reporter, result);
SkColor4f expectedNewColors[6] = {newColor, newColor, newColor, newColor, newColor, newColor};
check_compressed_mipmaps(context, img, compression, expectedNewColors, mipMapped, reporter,
"colorinit");
check_readback(context, std::move(img), compression, newColor, reporter, "solid readback");
context->deleteBackendTexture(backendTex);
}
@ -229,7 +244,30 @@ static void test_compressed_data_init(GrContext* context,
check_compressed_mipmaps(context, img, compression, expectedColors,
mipMapped, reporter, "pixmap");
check_readback(context, std::move(img), compression, expectedColors[0], reporter,
check_readback(context, img, compression, expectedColors[0], reporter, "data readback");
SkColor4f expectedColorsNew[6] = {
{1.0f, 1.0f, 0.0f, 1.0f}, // Y
{1.0f, 0.0f, 0.0f, 1.0f}, // R
{0.0f, 1.0f, 0.0f, 1.0f}, // G
{0.0f, 0.0f, 1.0f, 1.0f}, // B
{0.0f, 1.0f, 1.0f, 1.0f}, // C
{1.0f, 0.0f, 1.0f, 1.0f}, // M
};
std::unique_ptr<const char[]> dataNew(
make_compressed_data(compression, expectedColorsNew, mipMapped));
size_t dataNewSize =
SkCompressedDataSize(compression, {32, 32}, nullptr, mipMapped == GrMipMapped::kYes);
bool result = context->updateCompressedBackendTexture(backendTex, dataNew.get(), dataNewSize,
nullptr, nullptr);
// Since we were able to create the compressed texture we should be able to update it.
REPORTER_ASSERT(reporter, result);
check_compressed_mipmaps(context, img, compression, expectedColorsNew, mipMapped, reporter,
"pixmap");
check_readback(context, std::move(img), compression, expectedColorsNew[0], reporter,
"data readback");
context->deleteBackendTexture(backendTex);