diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 35f34f42a28ee..3a8b661be996e 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -695,6 +695,30 @@ bool GrContext::updateBackendTexture(const GrBackendTexture& backendTexture, ////////////////////////////////////////////////////////////////////////////// +static GrBackendTexture create_and_update_compressed_backend_texture( + GrContext* context, + SkISize dimensions, + const GrBackendFormat& backendFormat, + GrMipMapped mipMapped, + GrProtected isProtected, + sk_sp finishedCallback, + const GrGpu::BackendTextureData* data) { + GrGpu* gpu = context->priv().getGpu(); + + GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat, + mipMapped, isProtected); + if (!beTex.isValid()) { + return {}; + } + + if (!context->priv().getGpu()->updateCompressedBackendTexture( + beTex, std::move(finishedCallback), data)) { + context->deleteBackendTexture(beTex); + return {}; + } + return beTex; +} + GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height, const GrBackendFormat& backendFormat, const SkColor4f& color, @@ -717,9 +741,9 @@ GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height } GrGpu::BackendTextureData data(color); - return fGpu->createCompressedBackendTexture({width, height}, backendFormat, - mipMapped, isProtected, std::move(finishedCallback), - &data); + return create_and_update_compressed_backend_texture(this, {width, height}, backendFormat, + mipMapped, isProtected, + std::move(finishedCallback), &data); } GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height, @@ -759,9 +783,9 @@ GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height } GrGpu::BackendTextureData data(compressedData, dataSize); - return fGpu->createCompressedBackendTexture({width, height}, backendFormat, - mipMapped, isProtected, std::move(finishedCallback), - &data); + return create_and_update_compressed_backend_texture(this, {width, height}, backendFormat, + mipMapped, isProtected, + std::move(finishedCallback), &data); } GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height, diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index a38a51a3462b8..d8c4607dfe401 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -932,9 +932,7 @@ bool GrGpu::updateBackendTexture(const GrBackendTexture& backendTexture, GrBackendTexture GrGpu::createCompressedBackendTexture(SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected isProtected, - sk_sp finishedCallback, - const BackendTextureData* data) { + GrProtected isProtected) { const GrCaps* caps = this->caps(); if (!format.isValid()) { @@ -957,12 +955,38 @@ GrBackendTexture GrGpu::createCompressedBackendTexture(SkISize dimensions, return {}; } - if (!CompressedDataIsCorrect(dimensions, compressionType, mipMapped, data)) { - return {}; + return this->onCreateCompressedBackendTexture(dimensions, format, mipMapped, isProtected); +} + +bool GrGpu::updateCompressedBackendTexture(const GrBackendTexture& backendTexture, + sk_sp finishedCallback, + const BackendTextureData* data) { + SkASSERT(data); + + if (!backendTexture.isValid()) { + return false; + } + + GrBackendFormat format = backendTexture.getBackendFormat(); + + SkImage::CompressionType compressionType = GrBackendFormatToCompressionType(format); + if (compressionType == SkImage::CompressionType::kNone) { + // Uncompressed formats must go through the createBackendTexture API + return false; + } + + if (backendTexture.hasMipMaps() && !this->caps()->mipMapSupport()) { + return false; + } + + GrMipMapped mipMapped = backendTexture.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo; + + if (!CompressedDataIsCorrect(backendTexture.dimensions(), compressionType, mipMapped, data)) { + return false; } - return this->onCreateCompressedBackendTexture(dimensions, format, mipMapped, - isProtected, std::move(finishedCallback), data); + return this->onUpdateCompressedBackendTexture(backendTexture, std::move(finishedCallback), + data); } GrStagingBuffer* GrGpu::findStagingBuffer(size_t size) { diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index f793a93c62b0e..f0944bc2a7e8f 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -617,9 +617,11 @@ class GrGpu : public SkRefCnt { GrBackendTexture createCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*); + GrProtected); + + bool updateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*); virtual bool setBackendTextureState(const GrBackendTexture&, const GrBackendSurfaceMutableState&, @@ -741,13 +743,16 @@ class GrGpu : public SkRefCnt { GrProtected) = 0; virtual GrBackendTexture onCreateCompressedBackendTexture( - SkISize dimensions, const GrBackendFormat&, GrMipMapped, GrProtected, - sk_sp finishedCallback, const BackendTextureData*) = 0; + SkISize dimensions, const GrBackendFormat&, GrMipMapped, GrProtected) = 0; virtual bool onUpdateBackendTexture(const GrBackendTexture&, sk_sp finishedCallback, const BackendTextureData*) = 0; + virtual bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) = 0; + // called when the 3D context state is unknown. Subclass should emit any // assumed 3D context state and dirty any state cache. virtual void onResetContext(uint32_t resetBits) = 0; diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp index 809ff1169d826..200bd5f0778f6 100644 --- a/src/gpu/d3d/GrD3DGpu.cpp +++ b/src/gpu/d3d/GrD3DGpu.cpp @@ -1071,8 +1071,7 @@ bool GrD3DGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture, GrBackendTexture GrD3DGpu::onCreateCompressedBackendTexture( SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected isProtected, sk_sp finishedCallback, - const BackendTextureData* data) { + GrProtected isProtected) { this->handleDirtyContext(); const GrD3DCaps& caps = this->d3dCaps(); @@ -1101,6 +1100,12 @@ GrBackendTexture GrD3DGpu::onCreateCompressedBackendTexture( return GrBackendTexture(dimensions.width(), dimensions.height(), info); } +bool GrD3DGpu::onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) { + return false; +} + void GrD3DGpu::deleteBackendTexture(const GrBackendTexture& tex) { SkASSERT(GrBackendApi::kDirect3D == tex.fBackend); // Nothing to do here, will get cleaned up when the GrBackendTexture object goes away diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h index ab60be0264ca0..2467509b8cc18 100644 --- a/src/gpu/d3d/GrD3DGpu.h +++ b/src/gpu/d3d/GrD3DGpu.h @@ -207,9 +207,11 @@ class GrD3DGpu : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*) override; + GrProtected) override; + + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override; bool submitDirectCommandList(SyncQueue sync); diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp index 59c09511ef32b..d431f7afbdaf2 100644 --- a/src/gpu/dawn/GrDawnGpu.cpp +++ b/src/gpu/dawn/GrDawnGpu.cpp @@ -404,11 +404,16 @@ bool GrDawnGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture, } GrBackendTexture GrDawnGpu::onCreateCompressedBackendTexture( - SkISize dimensions, const GrBackendFormat&, GrMipMapped, GrProtected, - sk_sp finishedCallback, const BackendTextureData*) { + SkISize dimensions, const GrBackendFormat&, GrMipMapped, GrProtected) { return {}; } +bool GrDawnGpu::onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) { + return false; +} + void GrDawnGpu::deleteBackendTexture(const GrBackendTexture& tex) { GrDawnTextureInfo info; if (tex.getDawnTextureInfo(&info)) { diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h index 282ddc44f98ac..2be5f28404734 100644 --- a/src/gpu/dawn/GrDawnGpu.h +++ b/src/gpu/dawn/GrDawnGpu.h @@ -149,9 +149,11 @@ class GrDawnGpu : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*) override; + GrProtected) override; + + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override; sk_sp onCreateBuffer(size_t size, GrGpuBufferType type, GrAccessPattern, const void* data) override; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 6820f76576999..9cf8ac92be645 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -1392,12 +1392,19 @@ sk_sp GrGLGpu::onCreateCompressedTexture(SkISize dimensions, desc.fOwnership = GrBackendObjectOwnership::kOwned; desc.fFormat = format.asGLFormat(); desc.fID = this->createCompressedTexture2D(desc.fSize, compression, desc.fFormat, - mipMapped, &initialState, - data, dataSize); + mipMapped, &initialState); if (!desc.fID) { return nullptr; } + if (data) { + if (!this->uploadCompressedTexData(compression, desc.fFormat, dimensions, mipMapped, + GR_GL_TEXTURE_2D, data, dataSize)) { + GL_CALL(DeleteTextures(1, &desc.fID)); + return nullptr; + } + } + // Unbind this texture from the scratch texture unit. this->bindTextureToScratchUnit(GR_GL_TEXTURE_2D, 0); @@ -1414,8 +1421,7 @@ sk_sp GrGLGpu::onCreateCompressedTexture(SkISize dimensions, GrBackendTexture GrGLGpu::onCreateCompressedBackendTexture( SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected isProtected, sk_sp finishedCallback, - const BackendTextureData* data) { + GrProtected isProtected) { // We don't support protected textures in GL. if (isProtected == GrProtected::kYes) { return {}; @@ -1430,34 +1436,13 @@ GrBackendTexture GrGLGpu::onCreateCompressedBackendTexture( SkImage::CompressionType compression = GrBackendFormatToCompressionType(format); - const char* rawData = nullptr; - size_t rawDataSize = 0; - SkAutoMalloc am; - SkASSERT(!data || data->type() != BackendTextureData::Type::kPixmaps); - if (data && data->type() == BackendTextureData::Type::kCompressed) { - rawData = (const char*) data->compressedData(); - rawDataSize = data->compressedSize(); - } else if (data && data->type() == BackendTextureData::Type::kColor) { - SkASSERT(compression != SkImage::CompressionType::kNone); - - rawDataSize = SkCompressedDataSize(compression, dimensions, nullptr, - mipMapped == GrMipMapped::kYes); - - am.reset(rawDataSize); - - GrFillInCompressedData(compression, dimensions, mipMapped, (char*)am.get(), data->color()); - - rawData = (const char*) am.get(); - } - GrGLTextureInfo info; GrGLTextureParameters::SamplerOverriddenState initialState; info.fTarget = GR_GL_TEXTURE_2D; info.fFormat = GrGLFormatToEnum(glFormat); info.fID = this->createCompressedTexture2D(dimensions, compression, glFormat, - mipMapped, &initialState, - rawData, rawDataSize); + mipMapped, &initialState); if (!info.fID) { return {}; } @@ -1474,6 +1459,55 @@ GrBackendTexture GrGLGpu::onCreateCompressedBackendTexture( std::move(parameters)); } +bool GrGLGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture, + sk_sp finishedCallback, + const BackendTextureData* data) { + SkASSERT(data && data->type() != BackendTextureData::Type::kPixmaps); + + GrGLTextureInfo info; + SkAssertResult(backendTexture.getGLTextureInfo(&info)); + + GrBackendFormat format = backendTexture.getBackendFormat(); + GrGLFormat glFormat = format.asGLFormat(); + if (glFormat == GrGLFormat::kUnknown) { + return false; + } + SkImage::CompressionType compression = GrBackendFormatToCompressionType(format); + + GrMipMapped mipMapped = backendTexture.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo; + + const char* rawData = nullptr; + size_t rawDataSize = 0; + SkAutoMalloc am; + if (data->type() == BackendTextureData::Type::kCompressed) { + rawData = (const char*)data->compressedData(); + rawDataSize = data->compressedSize(); + } else { + SkASSERT(data->type() == BackendTextureData::Type::kColor); + SkASSERT(compression != SkImage::CompressionType::kNone); + + rawDataSize = SkCompressedDataSize(compression, backendTexture.dimensions(), nullptr, + backendTexture.hasMipMaps()); + + am.reset(rawDataSize); + + GrFillInCompressedData(compression, backendTexture.dimensions(), mipMapped, (char*)am.get(), + data->color()); + + rawData = (const char*)am.get(); + } + + this->bindTextureToScratchUnit(info.fTarget, info.fID); + bool result = this->uploadCompressedTexData( + compression, glFormat, backendTexture.dimensions(), mipMapped, GR_GL_TEXTURE_2D, + rawData, rawDataSize); + + // Unbind this texture from the scratch texture unit. + this->bindTextureToScratchUnit(info.fTarget, 0); + + return result; +} + namespace { const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; @@ -1581,8 +1615,7 @@ GrGLuint GrGLGpu::createCompressedTexture2D( SkImage::CompressionType compression, GrGLFormat format, GrMipMapped mipMapped, - GrGLTextureParameters::SamplerOverriddenState* initialState, - const void* data, size_t dataSize) { + GrGLTextureParameters::SamplerOverriddenState* initialState) { if (format == GrGLFormat::kUnknown) { return 0; } @@ -1596,14 +1629,6 @@ GrGLuint GrGLGpu::createCompressedTexture2D( *initialState = set_initial_texture_params(this->glInterface(), GR_GL_TEXTURE_2D); - if (data) { - if (!this->uploadCompressedTexData(compression, format, dimensions, mipMapped, - GR_GL_TEXTURE_2D, data, dataSize)) { - GL_CALL(DeleteTextures(1, &id)); - return 0; - } - } - return id; } diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 1305780028097..3c2e7485927b4 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -201,14 +201,16 @@ class GrGLGpu final : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*) override; + GrProtected) override; bool onUpdateBackendTexture(const GrBackendTexture&, sk_sp finishedCallback, const BackendTextureData*) override; + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override; + void onResetContext(uint32_t resetBits) override; void onResetTextureBindings() override; @@ -271,8 +273,7 @@ class GrGLGpu final : public GrGpu { SkImage::CompressionType compression, GrGLFormat, GrMipMapped, - GrGLTextureParameters::SamplerOverriddenState*, - const void* data, size_t dataSize); + GrGLTextureParameters::SamplerOverriddenState*); bool onReadPixels(GrSurface*, int left, int top, int width, int height, GrColorType surfaceColorType, GrColorType dstColorType, void* buffer, diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp index 3890ce4708d6d..ecbde5a8ea996 100644 --- a/src/gpu/mock/GrMockGpu.cpp +++ b/src/gpu/mock/GrMockGpu.cpp @@ -296,7 +296,7 @@ GrBackendTexture GrMockGpu::onCreateBackendTexture(SkISize dimensions, GrBackendTexture GrMockGpu::onCreateCompressedBackendTexture( SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected, sk_sp finishedCallback, const BackendTextureData*) { + GrProtected) { SkImage::CompressionType compression = format.asMockCompressionType(); if (compression == SkImage::CompressionType::kNone) { return {}; // should go through onCreateBackendTexture diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h index 0abebfca56fb3..a7e76c5ed9739 100644 --- a/src/gpu/mock/GrMockGpu.h +++ b/src/gpu/mock/GrMockGpu.h @@ -161,9 +161,14 @@ class GrMockGpu : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*) override; + GrProtected) override; + + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override { + return true; + } + void deleteBackendTexture(const GrBackendTexture&) override; bool compile(const GrProgramDesc&, const GrProgramInfo&) override { return false; } diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 4bfd6d33c80ed..5b9af89e0f467 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -144,9 +144,11 @@ class GrMtlGpu : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallback, - const BackendTextureData*) override; + GrProtected) override; + + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override; sk_sp onCreateTexture(SkISize, const GrBackendFormat&, diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm index 7c188bf8346d9..576bcc1b88ab5 100644 --- a/src/gpu/mtl/GrMtlGpu.mm +++ b/src/gpu/mtl/GrMtlGpu.mm @@ -978,8 +978,7 @@ void copy_src_data(char* dst, size_t bytesPerPixel, const SkTArray& indi GrBackendTexture GrMtlGpu::onCreateCompressedBackendTexture( SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected isProtected, sk_sp finishedCallback, - const BackendTextureData* data) { + GrProtected isProtected) { const MTLPixelFormat mtlFormat = GrBackendFormatAsMTLPixelFormat(format); GrMtlTextureInfo info; @@ -988,16 +987,13 @@ void copy_src_data(char* dst, size_t bytesPerPixel, const SkTArray& indi return {}; } - GrBackendTexture backendTex(dimensions.width(), dimensions.height(), mipMapped, info); - - if (data) { - if (!this->onUpdateBackendTexture(backendTex, std::move(finishedCallback), data)) { - this->deleteBackendTexture(backendTex); - return {}; - } - } + return GrBackendTexture(dimensions.width(), dimensions.height(), mipMapped, info); +} - return backendTex; +bool GrMtlGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture, + sk_sp finishedCallback, + const BackendTextureData* data) { + return this->onUpdateBackendTexture(backendTexture, std::move(finishedCallback), data); } void GrMtlGpu::deleteBackendTexture(const GrBackendTexture& tex) { diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp index d66490ed67dfc..65372bc61c382 100644 --- a/src/gpu/vk/GrVkGpu.cpp +++ b/src/gpu/vk/GrVkGpu.cpp @@ -1765,8 +1765,7 @@ GrBackendTexture GrVkGpu::onCreateBackendTexture(SkISize dimensions, GrBackendTexture GrVkGpu::onCreateCompressedBackendTexture( SkISize dimensions, const GrBackendFormat& format, GrMipMapped mipMapped, - GrProtected isProtected, sk_sp finishedCallback, - const BackendTextureData* data) { + GrProtected isProtected) { this->handleDirtyContext(); const GrVkCaps& caps = this->vkCaps(); @@ -1796,15 +1795,13 @@ GrBackendTexture GrVkGpu::onCreateCompressedBackendTexture( return {}; } - GrBackendTexture beTex(dimensions.width(), dimensions.height(), info); + return GrBackendTexture(dimensions.width(), dimensions.height(), info); +} - if (data) { - if (!this->onUpdateBackendTexture(beTex, std::move(finishedCallback), data)) { - this->deleteBackendTexture(beTex); - return {}; - } - } - return beTex; +bool GrVkGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture, + sk_sp finishedCallback, + const BackendTextureData* data) { + return this->onUpdateBackendTexture(backendTexture, std::move(finishedCallback), data); } void set_layout_and_queue_from_mutable_state(GrVkGpu* gpu, GrVkImage* image, diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h index d88746f2b83c5..32a244d46fb25 100644 --- a/src/gpu/vk/GrVkGpu.h +++ b/src/gpu/vk/GrVkGpu.h @@ -195,14 +195,16 @@ class GrVkGpu : public GrGpu { GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions, const GrBackendFormat&, GrMipMapped, - GrProtected, - sk_sp finishedCallbacks, - const BackendTextureData*) override; + GrProtected) override; bool onUpdateBackendTexture(const GrBackendTexture&, sk_sp finishedCallback, const BackendTextureData*) override; + bool onUpdateCompressedBackendTexture(const GrBackendTexture&, + sk_sp finishedCallback, + const BackendTextureData*) override; + bool setBackendSurfaceState(GrVkImageInfo info, sk_sp currentState, SkISize dimensions,