Reland "Add GrContext api to update compressed backend textures."

This reverts commit ceebe424b1.

Reason for revert: relanding with fix

Original change's description:
> Revert "Add GrContext api to update compressed backend textures."
> 
> This reverts commit 2c180304dc.
> 
> Reason for revert: attempted workaround did not fix techno spark so needs further investigation
> 
> Original change's description:
> > 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>
> 
> TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com
> 
> Change-Id: Ib5433def02dc5dad97dcdbd4476ced6de2361e6a
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: chromium:1099255
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/302576
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,bsalomon@google.com,robertphillips@google.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: chromium:1099255
Change-Id: Ie238a56b7f12fea8b6e251a050e5e2f4b20d2ede
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/304741
Reviewed-by: Greg Daniel <egdaniel@google.com>
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-22 12:09:26 -04:00 committed by Skia Commit-Bot
parent b047b0b885
commit 95afafb2b0
7 changed files with 162 additions and 16 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
* Rename GrMipMapped to GrMipmapped for consistency with new APIs.
Also rename GrBackendTexture::hasMipMaps() to GrBackendTexture::hasMipmaps()
https://review.skia.org/304576

View File

@ -670,6 +670,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

@ -852,6 +852,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

@ -57,7 +57,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fDetachStencilFromMSAABuffersBeforeReadPixels = false;
fDontSetBaseOrMaxLevelForExternalTextures = false;
fNeverDisableColorWrites = false;
fMustSetTexParameterMinFilterToEnableMipmapping = false;
fMustSetAnyTexParameterToEnableMipmapping = false;
fProgramBinarySupport = false;
fProgramParameterSupport = false;
fSamplerObjectSupport = false;
@ -3574,7 +3574,12 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
// We saw this bug on a TecnoSpark 3 Pro with a PowerVR GE8300.
// GL_VERSION: "OpenGL ES 3.2 build 1.10@51309121"
// Possibly this could be more limited by driver version or HW generation.
fMustSetTexParameterMinFilterToEnableMipmapping = true;
// When using samplers, we are seeing a bug where the gpu is sometimes not sampling the
// correct mip level data. A workaround to this issue is that when binding a texture we also
// set some texture state, and it seems like any inividual state works (e.g. min/mag filter,
// base level, max level, etc.). Currently we just set the min filter level every time we
// bind a texture as the workaround.
fMustSetAnyTexParameterToEnableMipmapping = true;
}
#endif

View File

@ -399,8 +399,8 @@ public:
bool neverDisableColorWrites() const { return fNeverDisableColorWrites; }
// Texture parameters must be used to enable MIP mapping even when a sampler object is used.
bool mustSetTexParameterMinFilterToEnableMipmapping() const {
return fMustSetTexParameterMinFilterToEnableMipmapping;
bool mustSetAnyTexParameterToEnableMipmapping() const {
return fMustSetAnyTexParameterToEnableMipmapping;
}
// Returns the observed maximum number of instances the driver can handle in a single draw call
@ -556,7 +556,7 @@ private:
bool fDetachStencilFromMSAABuffersBeforeReadPixels : 1;
bool fDontSetBaseOrMaxLevelForExternalTextures : 1;
bool fNeverDisableColorWrites : 1;
bool fMustSetTexParameterMinFilterToEnableMipmapping : 1;
bool fMustSetAnyTexParameterToEnableMipmapping : 1;
int fMaxInstancesPerDrawWithoutCrashing = 0;
uint32_t fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;

View File

@ -1491,6 +1491,25 @@ bool GrGLGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTe
}
this->bindTextureToScratchUnit(info.fTarget, info.fID);
// If we have mips make sure the base level is set to 0 and the max level set to numMipLevels-1
// so that the uploads go to the right levels.
if (backendTexture.hasMipMaps() && this->glCaps().mipmapLevelAndLodControlSupport()) {
auto params = backendTexture.getGLTextureParams();
GrGLTextureParameters::NonsamplerState nonsamplerState = params->nonsamplerState();
if (params->nonsamplerState().fBaseMipMapLevel != 0) {
GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_BASE_LEVEL, 0));
nonsamplerState.fBaseMipMapLevel = 0;
}
int numMipLevels =
SkMipmap::ComputeLevelCount(backendTexture.width(), backendTexture.height()) + 1;
if (params->nonsamplerState().fMaxMipmapLevel != (numMipLevels - 1)) {
GL_CALL(TexParameteri(info.fTarget, GR_GL_TEXTURE_MAX_LEVEL, numMipLevels - 1));
nonsamplerState.fBaseMipMapLevel = numMipLevels - 1;
}
params->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
}
bool result = this->uploadCompressedTexData(
compression, glFormat, backendTexture.dimensions(), mipMapped, GR_GL_TEXTURE_2D,
rawData, rawDataSize);
@ -2594,19 +2613,17 @@ void GrGLGpu::bindTexture(int unitIdx, GrSamplerState samplerState, const GrSwiz
GrGLTextureParameters::SamplerOverriddenState newSamplerState;
if (fSamplerObjectCache) {
fSamplerObjectCache->bindSampler(unitIdx, samplerState);
if (this->glCaps().mustSetTexParameterMinFilterToEnableMipmapping()) {
if (this->glCaps().mustSetAnyTexParameterToEnableMipmapping()) {
if (samplerState.mipmapped() == GrMipmapped::kYes) {
GrGLenum minFilter = filter_to_gl_min_filter(samplerState.filter(),
samplerState.mipmapMode());
const GrGLTextureParameters::SamplerOverriddenState& oldSamplerState =
texture->parameters()->samplerOverriddenState();
if (setAll || oldSamplerState.fMinFilter != minFilter) {
this->setTextureUnit(unitIdx);
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, minFilter));
newSamplerState = oldSamplerState;
newSamplerState.fMinFilter = minFilter;
samplerStateToRecord = &newSamplerState;
}
this->setTextureUnit(unitIdx);
GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, minFilter));
newSamplerState = oldSamplerState;
newSamplerState.fMinFilter = minFilter;
samplerStateToRecord = &newSamplerState;
}
}
} else {

View File

@ -158,8 +158,23 @@ static void test_compressed_color_init(GrDirectContext* dContext,
check_compressed_mipmaps(dContext, img, compression, expectedColors, mipMapped,
reporter, "colorinit");
check_readback(dContext, std::move(img), compression, color, reporter,
"solid readback");
check_readback(dContext, 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 = dContext->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(dContext, img, compression, expectedNewColors, mipMapped, reporter,
"colorinit");
check_readback(dContext, std::move(img), compression, newColor, reporter, "solid readback");
dContext->deleteBackendTexture(backendTex);
}
@ -230,7 +245,30 @@ static void test_compressed_data_init(GrDirectContext* dContext,
check_compressed_mipmaps(dContext, img, compression, expectedColors,
mipMapped, reporter, "pixmap");
check_readback(dContext, std::move(img), compression, expectedColors[0], reporter,
check_readback(dContext, 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 = dContext->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(dContext, img, compression, expectedColorsNew, mipMapped, reporter,
"pixmap");
check_readback(dContext, std::move(img), compression, expectedColorsNew[0], reporter,
"data readback");
dContext->deleteBackendTexture(backendTex);