Revert "Remove code to push pixmaps to backend textures from GrGpu classes"
This reverts commit 45889d12696f8e0af2796a6bbd3938b6d2614eca.
Reason for revert: compressed texture assertion on D3D bot
Original change's description:
> Remove code to push pixmaps to backend textures from GrGpu classes
>
> Replace GrGpu::updateBackendTexture with narrower method that clears
> a backend texture.
>
> Creation of data for a solid color compressed texture is lifted up to
> GrDirectContext and goes through updateCompressedBackendTexture.
>
> Bug: skia:11786
> Change-Id: I1d617623df5e65686f30e57c361a64f78d77f7bd
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/392836
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com
Change-Id: Ie58f52245c44c77f09742b0cb590cc97b97e6e37
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:11786
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/396097
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index b1413c8..99d2358 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -280,7 +280,6 @@
SkISize dimensions() const { return {fWidth, fHeight}; }
int width() const { return fWidth; }
int height() const { return fHeight; }
- GrMipmapped mipmapped() const { return fMipmapped; }
bool hasMipmaps() const { return fMipmapped == GrMipmapped::kYes; }
/** deprecated alias of hasMipmaps(). */
bool hasMipMaps() const { return this->hasMipmaps(); }
diff --git a/src/gpu/GrDataUtils.cpp b/src/gpu/GrDataUtils.cpp
index e5a7adf..ce8f7bb 100644
--- a/src/gpu/GrDataUtils.cpp
+++ b/src/gpu/GrDataUtils.cpp
@@ -686,7 +686,7 @@
return true;
}
-bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, std::array<float, 4> color) {
+bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, SkColor4f color) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
if (!dstInfo.isValid()) {
@@ -700,7 +700,7 @@
}
if (dstInfo.colorType() == GrColorType::kRGB_888) {
// SkRasterPipeline doesn't handle writing to RGB_888. So we handle that specially here.
- uint32_t rgba = SkColor4f{color[0], color[1], color[2], color[3]}.toBytes_RGBA();
+ uint32_t rgba = color.toBytes_RGBA();
for (int y = 0; y < dstInfo.height(); ++y) {
char* d = static_cast<char*>(dst) + y * dstRB;
for (int x = 0; x < dstInfo.width(); ++x, d += 3) {
@@ -719,7 +719,7 @@
char block[64];
SkArenaAlloc alloc(block, sizeof(block), 1024);
SkRasterPipeline_<256> pipeline;
- pipeline.append_constant_color(&alloc, color.data());
+ pipeline.append_constant_color(&alloc, color);
switch (lumMode) {
case LumMode::kNone:
break;
diff --git a/src/gpu/GrDataUtils.h b/src/gpu/GrDataUtils.h
index ff58246..dbc9661 100644
--- a/src/gpu/GrDataUtils.h
+++ b/src/gpu/GrDataUtils.h
@@ -39,7 +39,7 @@
bool GrConvertPixels(const GrPixmap& dst, const GrCPixmap& src, bool flipY = false);
/** Clears the dst image to a constant color. */
-bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, std::array<float, 4> color);
+bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, SkColor4f color);
#if GR_TEST_UTILS
/**
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index 4b0a867..69f60c5 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -10,9 +10,7 @@
#include "include/core/SkTraceMemoryDump.h"
#include "include/gpu/GrContextThreadSafeProxy.h"
-#include "src/core/SkAutoMalloc.h"
#include "src/core/SkTaskGroup.h"
-#include "src/gpu/GrBackendUtils.h"
#include "src/gpu/GrClientMappedBufferManager.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrDirectContextPriv.h"
@@ -474,24 +472,26 @@
return this->createBackendTexture(width, height, format, mipMapped, renderable, isProtected);
}
-static GrBackendTexture create_and_clear_backend_texture(GrDirectContext* dContext,
- SkISize dimensions,
- const GrBackendFormat& backendFormat,
- GrMipmapped mipMapped,
- GrRenderable renderable,
- GrProtected isProtected,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+static GrBackendTexture create_and_update_backend_texture(
+ GrDirectContext* dContext,
+ SkISize dimensions,
+ const GrBackendFormat& backendFormat,
+ GrMipmapped mipMapped,
+ GrRenderable renderable,
+ GrProtected isProtected,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const GrGpu::BackendTextureData* data) {
GrGpu* gpu = dContext->priv().getGpu();
+ SkASSERT(data->type() == GrGpu::BackendTextureData::Type::kColor);
GrBackendTexture beTex = gpu->createBackendTexture(dimensions, backendFormat, renderable,
mipMapped, isProtected);
if (!beTex.isValid()) {
return {};
}
- if (!dContext->priv().getGpu()->clearBackendTexture(beTex,
- std::move(finishedCallback),
- color)) {
+ if (!dContext->priv().getGpu()->updateBackendTexture(beTex,
+ std::move(finishedCallback),
+ data)) {
dContext->deleteBackendTexture(beTex);
return {};
}
@@ -555,14 +555,10 @@
return {};
}
- return create_and_clear_backend_texture(this,
- {width, height},
- backendFormat,
- mipMapped,
- renderable,
- isProtected,
- std::move(finishedCallback),
- color.array());
+ GrGpu::BackendTextureData data(color);
+ return create_and_update_backend_texture(this, {width, height},
+ backendFormat, mipMapped, renderable, isProtected,
+ std::move(finishedCallback), &data);
}
GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
@@ -587,14 +583,10 @@
GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
SkColor4f swizzledColor = this->caps()->getWriteSwizzle(format, grColorType).applyTo(color);
- return create_and_clear_backend_texture(this,
- {width, height},
- format,
- mipMapped,
- renderable,
- isProtected,
- std::move(finishedCallback),
- swizzledColor.array());
+ GrGpu::BackendTextureData data(swizzledColor);
+ return create_and_update_backend_texture(this, {width, height}, format,
+ mipMapped, renderable, isProtected,
+ std::move(finishedCallback), &data);
}
GrBackendTexture GrDirectContext::createBackendTexture(const SkPixmap srcData[],
@@ -655,7 +647,8 @@
return false;
}
- return fGpu->clearBackendTexture(backendTexture, std::move(finishedCallback), color.array());
+ GrGpu::BackendTextureData data(color);
+ return fGpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
@@ -677,11 +670,9 @@
}
GrSwizzle swizzle = this->caps()->getWriteSwizzle(format, grColorType);
- SkColor4f swizzledColor = swizzle.applyTo(color);
+ GrGpu::BackendTextureData data(swizzle.applyTo(color));
- return fGpu->clearBackendTexture(backendTexture,
- std::move(finishedCallback),
- swizzledColor.array());
+ return fGpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
@@ -726,8 +717,7 @@
GrMipmapped mipMapped,
GrProtected isProtected,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) {
+ const GrGpu::BackendTextureData* data) {
GrGpu* gpu = dContext->priv().getGpu();
GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat,
@@ -737,21 +727,20 @@
}
if (!dContext->priv().getGpu()->updateCompressedBackendTexture(
- beTex, std::move(finishedCallback), data, size)) {
+ beTex, std::move(finishedCallback), data)) {
dContext->deleteBackendTexture(beTex);
return {};
}
return beTex;
}
-GrBackendTexture GrDirectContext::createCompressedBackendTexture(
- int width, int height,
- const GrBackendFormat& backendFormat,
- const SkColor4f& color,
- GrMipmapped mipmapped,
- GrProtected isProtected,
- GrGpuFinishedProc finishedProc,
- GrGpuFinishedContext finishedContext) {
+GrBackendTexture GrDirectContext::createCompressedBackendTexture(int width, int height,
+ const GrBackendFormat& backendFormat,
+ const SkColor4f& color,
+ GrMipmapped mipMapped,
+ GrProtected isProtected,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
@@ -759,35 +748,19 @@
return {};
}
- SkImage::CompressionType compression = GrBackendFormatToCompressionType(backendFormat);
- if (compression == SkImage::CompressionType::kNone) {
- return {};
- }
-
- size_t size = SkCompressedDataSize(compression,
- {width, height},
- nullptr,
- mipmapped == GrMipmapped::kYes);
- auto storage = std::make_unique<char[]>(size);
- GrFillInCompressedData(compression, {width, height}, mipmapped, storage.get(), color);
- return create_and_update_compressed_backend_texture(this,
- {width, height},
- backendFormat,
- mipmapped,
- isProtected,
- std::move(finishedCallback),
- storage.get(),
- size);
+ GrGpu::BackendTextureData data(color);
+ return create_and_update_compressed_backend_texture(this, {width, height},
+ backendFormat, mipMapped, isProtected,
+ std::move(finishedCallback), &data);
}
-GrBackendTexture GrDirectContext::createCompressedBackendTexture(
- int width, int height,
- SkImage::CompressionType compression,
- const SkColor4f& color,
- GrMipmapped mipMapped,
- GrProtected isProtected,
- GrGpuFinishedProc finishedProc,
- GrGpuFinishedContext finishedContext) {
+GrBackendTexture GrDirectContext::createCompressedBackendTexture(int width, int height,
+ SkImage::CompressionType compression,
+ const SkColor4f& color,
+ GrMipmapped mipMapped,
+ GrProtected isProtected,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
GrBackendFormat format = this->compressedBackendFormat(compression);
return this->createCompressedBackendTexture(width, height, format, color,
@@ -795,15 +768,14 @@
finishedContext);
}
-GrBackendTexture GrDirectContext::createCompressedBackendTexture(
- int width, int height,
- const GrBackendFormat& backendFormat,
- const void* compressedData,
- size_t dataSize,
- GrMipmapped mipMapped,
- GrProtected isProtected,
- GrGpuFinishedProc finishedProc,
- GrGpuFinishedContext finishedContext) {
+GrBackendTexture GrDirectContext::createCompressedBackendTexture(int width, int height,
+ const GrBackendFormat& backendFormat,
+ const void* compressedData,
+ size_t dataSize,
+ GrMipmapped mipMapped,
+ GrProtected isProtected,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
@@ -811,24 +783,19 @@
return {};
}
- return create_and_update_compressed_backend_texture(this,
- {width, height},
- backendFormat,
- mipMapped,
- isProtected,
- std::move(finishedCallback),
- compressedData,
- dataSize);
+ GrGpu::BackendTextureData data(compressedData, dataSize);
+ return create_and_update_compressed_backend_texture(this, {width, height},
+ backendFormat, mipMapped, isProtected,
+ std::move(finishedCallback), &data);
}
-GrBackendTexture GrDirectContext::createCompressedBackendTexture(
- int width, int height,
- SkImage::CompressionType compression,
- const void* data, size_t dataSize,
- GrMipmapped mipMapped,
- GrProtected isProtected,
- GrGpuFinishedProc finishedProc,
- GrGpuFinishedContext finishedContext) {
+GrBackendTexture GrDirectContext::createCompressedBackendTexture(int width, int height,
+ SkImage::CompressionType compression,
+ const void* data, size_t dataSize,
+ GrMipmapped mipMapped,
+ GrProtected isProtected,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
GrBackendFormat format = this->compressedBackendFormat(compression);
return this->createCompressedBackendTexture(width, height, format, data, dataSize, mipMapped,
@@ -845,25 +812,8 @@
return false;
}
- SkImage::CompressionType compression =
- GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
- if (compression == SkImage::CompressionType::kNone) {
- return {};
- }
- size_t size = SkCompressedDataSize(compression,
- backendTexture.dimensions(),
- nullptr,
- backendTexture.hasMipmaps());
- SkAutoMalloc storage(size);
- GrFillInCompressedData(compression,
- backendTexture.dimensions(),
- backendTexture.mipmapped(),
- static_cast<char*>(storage.get()),
- color);
- return fGpu->updateCompressedBackendTexture(backendTexture,
- std::move(finishedCallback),
- storage.get(),
- size);
+ GrGpu::BackendTextureData data(color);
+ return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
bool GrDirectContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
@@ -881,10 +831,9 @@
return false;
}
- return fGpu->updateCompressedBackendTexture(backendTexture,
- std::move(finishedCallback),
- compressedData,
- dataSize);
+ GrGpu::BackendTextureData data(compressedData, dataSize);
+
+ return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 3d94791..22a0172 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -755,16 +755,58 @@
#endif // GR_GPU_STATS
#endif // GR_TEST_UTILS
-bool GrGpu::CompressedDataIsCorrect(SkISize dimensions,
- SkImage::CompressionType compressionType,
- GrMipmapped mipMapped,
- const void* data,
- size_t length) {
- size_t computedSize = SkCompressedDataSize(compressionType,
- dimensions,
- nullptr,
- mipMapped == GrMipmapped::kYes);
- return computedSize == length;
+bool GrGpu::MipMapsAreCorrect(SkISize dimensions,
+ GrMipmapped mipmapped,
+ const BackendTextureData* data) {
+ int numMipLevels = 1;
+ if (mipmapped == GrMipmapped::kYes) {
+ numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
+ }
+
+ if (!data || data->type() == BackendTextureData::Type::kColor) {
+ return true;
+ }
+
+ if (data->type() == BackendTextureData::Type::kCompressed) {
+ return false; // This should be going through CompressedDataIsCorrect
+ }
+
+ SkASSERT(data->type() == BackendTextureData::Type::kPixmaps);
+
+ if (data->pixmap(0).dimensions() != dimensions) {
+ return false;
+ }
+
+ GrColorType colorType = data->pixmap(0).colorType();
+ for (int i = 1; i < numMipLevels; ++i) {
+ dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
+ if (dimensions != data->pixmap(i).dimensions()) {
+ return false;
+ }
+ if (colorType != data->pixmap(i).colorType()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool GrGpu::CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType compressionType,
+ GrMipmapped mipMapped, const BackendTextureData* data) {
+
+ if (!data || data->type() == BackendTextureData::Type::kColor) {
+ return true;
+ }
+
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ return false;
+ }
+
+ SkASSERT(data->type() == BackendTextureData::Type::kCompressed);
+
+ size_t computedSize = SkCompressedDataSize(compressionType, dimensions,
+ nullptr, mipMapped == GrMipmapped::kYes);
+
+ return computedSize == data->compressedSize();
}
GrBackendTexture GrGpu::createBackendTexture(SkISize dimensions,
@@ -795,18 +837,33 @@
return this->onCreateBackendTexture(dimensions, format, renderable, mipMapped, isProtected);
}
-bool GrGpu::clearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrGpu::updateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
+ SkASSERT(data);
+ const GrCaps* caps = this->caps();
+
if (!backendTexture.isValid()) {
return false;
}
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ auto ct = data->pixmap(0).colorType();
+ if (!caps->areColorTypeAndFormatCompatible(ct, backendTexture.getBackendFormat())) {
+ return false;
+ }
+ }
+
if (backendTexture.hasMipmaps() && !this->caps()->mipmapSupport()) {
return false;
}
- return this->onClearBackendTexture(backendTexture, std::move(finishedCallback), color);
+ GrMipmapped mipmapped = backendTexture.hasMipmaps() ? GrMipmapped::kYes : GrMipmapped::kNo;
+ if (!MipMapsAreCorrect(backendTexture.dimensions(), mipmapped, data)) {
+ return false;
+ }
+
+ return this->onUpdateBackendTexture(backendTexture, std::move(finishedCallback), data);
}
GrBackendTexture GrGpu::createCompressedBackendTexture(SkISize dimensions,
@@ -840,8 +897,7 @@
bool GrGpu::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length) {
+ const BackendTextureData* data) {
SkASSERT(data);
if (!backendTexture.isValid()) {
@@ -862,16 +918,10 @@
GrMipmapped mipMapped = backendTexture.hasMipmaps() ? GrMipmapped::kYes : GrMipmapped::kNo;
- if (!CompressedDataIsCorrect(backendTexture.dimensions(),
- compressionType,
- mipMapped,
- data,
- length)) {
+ if (!CompressedDataIsCorrect(backendTexture.dimensions(), compressionType, mipMapped, data)) {
return false;
}
- return this->onUpdateCompressedBackendTexture(backendTexture,
- std::move(finishedCallback),
- data,
- length);
+ return this->onUpdateCompressedBackendTexture(backendTexture, std::move(finishedCallback),
+ data);
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 498668c..3c2b09d 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -498,6 +498,58 @@
Stats* stats() { return &fStats; }
void dumpJSON(SkJSONWriter*) const;
+ /** Used to initialize a backend texture with either a constant color, pixmaps or
+ * compressed data.
+ */
+ class BackendTextureData {
+ public:
+ enum class Type { kColor, kPixmaps, kCompressed };
+ BackendTextureData() = default;
+ BackendTextureData(const SkColor4f& color) : fType(Type::kColor), fColor(color) {}
+ BackendTextureData(const GrPixmap pixmaps[]) : fType(Type::kPixmaps), fPixmaps(pixmaps) {
+ SkASSERT(pixmaps);
+ }
+ BackendTextureData(const void* data, size_t size) : fType(Type::kCompressed) {
+ SkASSERT(data);
+ fCompressed.fData = data;
+ fCompressed.fSize = size;
+ }
+
+ Type type() const { return fType; }
+ SkColor4f color() const {
+ SkASSERT(this->type() == Type::kColor);
+ return fColor;
+ }
+
+ const GrPixmap& pixmap(int i) const {
+ SkASSERT(this->type() == Type::kPixmaps);
+ return fPixmaps[i];
+ }
+ const GrPixmap* pixmaps() const {
+ SkASSERT(this->type() == Type::kPixmaps);
+ return fPixmaps;
+ }
+
+ const void* compressedData() const {
+ SkASSERT(this->type() == Type::kCompressed);
+ return fCompressed.fData;
+ }
+ size_t compressedSize() const {
+ SkASSERT(this->type() == Type::kCompressed);
+ return fCompressed.fSize;
+ }
+
+ private:
+ Type fType = Type::kColor;
+ union {
+ SkColor4f fColor = {0, 0, 0, 0};
+ const GrPixmap* fPixmaps;
+ struct {
+ const void* fData;
+ size_t fSize;
+ } fCompressed;
+ };
+ };
/**
* Creates a texture directly in the backend API without wrapping it in a GrTexture.
@@ -519,9 +571,9 @@
GrMipmapped,
GrProtected);
- bool clearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color);
+ bool updateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*);
/**
* Same as the createBackendTexture case except compressed backend textures can
@@ -534,8 +586,7 @@
bool updateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length);
+ const BackendTextureData*);
virtual bool setBackendTextureState(const GrBackendTexture&,
const GrBackendSurfaceMutableState&,
@@ -635,11 +686,9 @@
virtual void xferBarrier(GrRenderTarget*, GrXferBarrierType) = 0;
protected:
- static bool CompressedDataIsCorrect(SkISize dimensions,
- SkImage::CompressionType,
- GrMipmapped,
- const void* data,
- size_t length);
+ static bool MipMapsAreCorrect(SkISize dimensions, GrMipmapped, const BackendTextureData*);
+ static bool CompressedDataIsCorrect(SkISize dimensions, SkImage::CompressionType,
+ GrMipmapped, const BackendTextureData*);
// Handles cases where a surface will be updated without a call to flushRenderTarget.
void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds,
@@ -662,14 +711,13 @@
virtual GrBackendTexture onCreateCompressedBackendTexture(
SkISize dimensions, const GrBackendFormat&, GrMipmapped, GrProtected) = 0;
- virtual bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) = 0;
+ virtual bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) = 0;
virtual bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length) = 0;
+ const BackendTextureData*) = 0;
// called when the 3D context state is unknown. Subclass should emit any
// assumed 3D context state and dirty any state cache.
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index 1b62dcf..209c30e 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -995,12 +995,32 @@
return GrBackendTexture(dimensions.width(), dimensions.height(), info);
}
-static bool copy_color_data(const GrD3DCaps& caps,
- char* mapPtr,
- DXGI_FORMAT dxgiFormat,
- SkISize dimensions,
+static void copy_src_data(char* mapPtr,
+ DXGI_FORMAT dxgiFormat,
+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT* placedFootprints,
+ const GrPixmap srcData[],
+ int numMipLevels) {
+ SkASSERT(srcData && numMipLevels);
+ SkASSERT(!GrDxgiFormatIsCompressed(dxgiFormat));
+ SkASSERT(mapPtr);
+
+ size_t bytesPerPixel = GrDxgiFormatBytesPerBlock(dxgiFormat);
+
+ for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
+ const size_t trimRowBytes = srcData[currentMipLevel].width() * bytesPerPixel;
+
+ // copy data into the buffer, skipping any trailing bytes
+ char* dst = mapPtr + placedFootprints[currentMipLevel].Offset;
+ SkRectMemcpy(dst, placedFootprints[currentMipLevel].Footprint.RowPitch,
+ srcData[currentMipLevel].addr(), srcData[currentMipLevel].rowBytes(),
+ trimRowBytes, srcData[currentMipLevel].height());
+ }
+}
+
+static bool copy_color_data(const GrD3DCaps& caps, char* mapPtr,
+ DXGI_FORMAT dxgiFormat, SkISize dimensions,
D3D12_PLACED_SUBRESOURCE_FOOTPRINT* placedFootprints,
- std::array<float, 4> color) {
+ SkColor4f color) {
auto colorType = caps.getFormatColorType(dxgiFormat);
if (colorType == GrColorType::kUnknown) {
return false;
@@ -1013,12 +1033,11 @@
return true;
}
-bool GrD3DGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrD3DGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
GrD3DTextureResourceInfo info;
SkAssertResult(backendTexture.getD3DTextureResourceInfo(&info));
- SkASSERT(!GrDxgiFormatIsCompressed(info.fFormat));
sk_sp<GrD3DResourceState> state = backendTexture.getGrD3DResourceState();
SkASSERT(state);
@@ -1042,23 +1061,27 @@
D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
unsigned int mipLevelCount = 1;
if (backendTexture.fMipmapped == GrMipmapped::kYes) {
- mipLevelCount = SkMipmap::ComputeLevelCount(backendTexture.dimensions()) + 1;
+ mipLevelCount = SkMipmap::ComputeLevelCount(backendTexture.dimensions().width(),
+ backendTexture.dimensions().height()) + 1;
}
SkASSERT(mipLevelCount == info.fLevelCount);
- SkAutoSTMalloc<15, D3D12_PLACED_SUBRESOURCE_FOOTPRINT> placedFootprints(mipLevelCount);
- UINT numRows;
- UINT64 rowSizeInBytes;
+ SkAutoTMalloc<D3D12_PLACED_SUBRESOURCE_FOOTPRINT> placedFootprints(mipLevelCount);
UINT64 combinedBufferSize;
- // We reuse the same top-level buffer area for all levels, hence passing 1 for level count.
- fDevice->GetCopyableFootprints(&desc,
- /* first resource */ 0,
- /* mip level count */ 1,
- /* base offset */ 0,
- placedFootprints.get(),
- &numRows,
- &rowSizeInBytes,
- &combinedBufferSize);
+ SkAutoTMalloc<UINT> numRows(mipLevelCount);
+ SkAutoTMalloc<UINT64> rowSizeInBytes(mipLevelCount);
+ fDevice->GetCopyableFootprints(&desc, 0, mipLevelCount, 0, placedFootprints.get(),
+ numRows.get(), rowSizeInBytes.get(), &combinedBufferSize);
SkASSERT(combinedBufferSize);
+ if (data->type() == BackendTextureData::Type::kColor &&
+ !GrDxgiFormatIsCompressed(info.fFormat) && mipLevelCount > 1) {
+ // For a single uncompressed color, we reuse the same top-level buffer area for all levels.
+ combinedBufferSize =
+ placedFootprints[0].Footprint.RowPitch * placedFootprints[0].Footprint.Height;
+ for (unsigned int i = 1; i < mipLevelCount; ++i) {
+ placedFootprints[i].Offset = 0;
+ placedFootprints[i].Footprint.RowPitch = placedFootprints[0].Footprint.RowPitch;
+ }
+ }
GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
@@ -1068,37 +1091,42 @@
char* bufferData = (char*)slice.fOffsetMapPtr;
SkASSERT(bufferData);
- if (!copy_color_data(this->d3dCaps(),
- bufferData,
- info.fFormat,
- backendTexture.dimensions(),
- placedFootprints,
- color)) {
- return false;
+
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ copy_src_data(bufferData, info.fFormat, placedFootprints.get(), data->pixmaps(),
+ info.fLevelCount);
+ } else if (data->type() == BackendTextureData::Type::kCompressed) {
+ copy_compressed_data(bufferData, info.fFormat, placedFootprints.get(), numRows.get(),
+ rowSizeInBytes.get(), data->compressedData(), info.fLevelCount);
+ } else {
+ SkASSERT(data->type() == BackendTextureData::Type::kColor);
+ SkImage::CompressionType compression =
+ GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
+ if (SkImage::CompressionType::kNone == compression) {
+ if (!copy_color_data(this->d3dCaps(), bufferData, info.fFormat,
+ backendTexture.dimensions(), placedFootprints, data->color())) {
+ return false;
+ }
+ } else {
+ size_t totalCompressedSize = SkCompressedFormatDataSize(compression,
+ backendTexture.dimensions(),
+ backendTexture.hasMipmaps());
+ SkAutoTMalloc<char> tempData(totalCompressedSize);
+ GrFillInCompressedData(compression, backendTexture.dimensions(),
+ backendTexture.fMipmapped, tempData, data->color());
+ copy_compressed_data(bufferData, info.fFormat, placedFootprints.get(), numRows.get(),
+ rowSizeInBytes.get(), tempData.get(), info.fLevelCount);
+ }
}
- // Update the offsets in the footprint to be relative to the slice's offset
- placedFootprints[0].Offset += slice.fOffset;
- // Since we're sharing data for all the levels, set all the upper level footprints to the base.
- UINT w = placedFootprints[0].Footprint.Width;
- UINT h = placedFootprints[0].Footprint.Height;
- for (unsigned int i = 1; i < mipLevelCount; ++i) {
- w = std::max(1U, w/2);
- h = std::max(1U, h/2);
- placedFootprints[i].Offset = placedFootprints[0].Offset;
- placedFootprints[i].Footprint.Format = placedFootprints[0].Footprint.Format;
- placedFootprints[i].Footprint.Width = w;
- placedFootprints[i].Footprint.Height = h;
- placedFootprints[i].Footprint.Depth = 1;
- placedFootprints[i].Footprint.RowPitch = placedFootprints[0].Footprint.RowPitch;
+
+ // Update the offsets in the footprints to be relative to the slice's offset
+ for (unsigned int i = 0; i < mipLevelCount; ++i) {
+ placedFootprints[i].Offset += slice.fOffset;
}
ID3D12Resource* d3dBuffer = static_cast<GrD3DBuffer*>(slice.fBuffer)->d3dResource();
- cmdList->copyBufferToTexture(d3dBuffer,
- texture.get(),
- mipLevelCount,
- placedFootprints.get(),
- /*left*/ 0,
- /*top */ 0);
+ cmdList->copyBufferToTexture(d3dBuffer, texture.get(), mipLevelCount, placedFootprints.get(), 0,
+ 0);
if (finishedCallback) {
this->addFinishedCallback(std::move(finishedCallback));
@@ -1116,88 +1144,8 @@
bool GrD3DGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) {
- GrD3DTextureResourceInfo info;
- SkAssertResult(backendTexture.getD3DTextureResourceInfo(&info));
-
- sk_sp<GrD3DResourceState> state = backendTexture.getGrD3DResourceState();
- SkASSERT(state);
- sk_sp<GrD3DTexture> texture = GrD3DTexture::MakeWrappedTexture(this,
- backendTexture.dimensions(),
- GrWrapCacheable::kNo,
- kRW_GrIOType,
- info,
- std::move(state));
- if (!texture) {
- return false;
- }
-
- GrD3DDirectCommandList* cmdList = this->currentCommandList();
- if (!cmdList) {
- return false;
- }
-
- texture->setResourceState(this, D3D12_RESOURCE_STATE_COPY_DEST);
-
- ID3D12Resource* d3dResource = texture->d3dResource();
- SkASSERT(d3dResource);
- D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
- unsigned int mipLevelCount = 1;
- if (backendTexture.hasMipmaps()) {
- mipLevelCount = SkMipmap::ComputeLevelCount(backendTexture.dimensions().width(),
- backendTexture.dimensions().height()) + 1;
- }
- SkASSERT(mipLevelCount == info.fLevelCount);
- SkAutoTMalloc<D3D12_PLACED_SUBRESOURCE_FOOTPRINT> placedFootprints(mipLevelCount);
- UINT64 combinedBufferSize;
- SkAutoTMalloc<UINT> numRows(mipLevelCount);
- SkAutoTMalloc<UINT64> rowSizeInBytes(mipLevelCount);
- fDevice->GetCopyableFootprints(&desc,
- 0,
- mipLevelCount,
- 0,
- placedFootprints.get(),
- numRows.get(),
- rowSizeInBytes.get(),
- &combinedBufferSize);
- SkASSERT(combinedBufferSize);
- SkASSERT(!GrDxgiFormatIsCompressed(info.fFormat));
-
- GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
- combinedBufferSize, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
- if (!slice.fBuffer) {
- return false;
- }
-
- char* bufferData = (char*)slice.fOffsetMapPtr;
- SkASSERT(bufferData);
- copy_compressed_data(bufferData,
- info.fFormat,
- placedFootprints.get(),
- numRows.get(),
- rowSizeInBytes.get(),
- data,
- info.fLevelCount);
-
- // Update the offsets in the footprints to be relative to the slice's offset
- for (unsigned int i = 0; i < mipLevelCount; ++i) {
- placedFootprints[i].Offset += slice.fOffset;
- }
-
- ID3D12Resource* d3dBuffer = static_cast<GrD3DBuffer*>(slice.fBuffer)->d3dResource();
- cmdList->copyBufferToTexture(d3dBuffer,
- texture.get(),
- mipLevelCount,
- placedFootprints.get(),
- 0,
- 0);
-
- if (finishedCallback) {
- this->addFinishedCallback(std::move(finishedCallback));
- }
-
- return true;
+ const BackendTextureData* data) {
+ return this->onUpdateBackendTexture(backendTexture, std::move(finishedCallback), data);
}
void GrD3DGpu::deleteBackendTexture(const GrBackendTexture& tex) {
diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h
index 7b6db87..fe952b8 100644
--- a/src/gpu/d3d/GrD3DGpu.h
+++ b/src/gpu/d3d/GrD3DGpu.h
@@ -218,9 +218,9 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override;
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override;
GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
const GrBackendFormat&,
@@ -229,8 +229,7 @@
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) override;
+ const BackendTextureData*) override;
bool submitDirectCommandList(SyncQueue sync);
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 1de6d60..092216c 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -382,23 +382,35 @@
}
}
-bool GrDawnGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrDawnGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
GrDawnTextureInfo info;
SkAssertResult(backendTexture.getDawnTextureInfo(&info));
+ size_t bpp = GrDawnBytesPerBlock(info.fFormat);
+ size_t baseLayerSize = bpp * backendTexture.width() * backendTexture.height();
+ const void* pixels;
+ SkAutoMalloc defaultStorage(baseLayerSize);
+ if (data && data->type() == BackendTextureData::Type::kPixmaps) {
+ int numMipLevels = info.fLevelCount;
+ SkAutoTArray<GrMipLevel> texels(numMipLevels);
+ GrColorType colorType = data->pixmap(0).colorType();
+ for (int i = 0; i < numMipLevels; ++i) {
+ texels[i] = {data->pixmap(i).addr(), data->pixmap(i).rowBytes(), nullptr};
+ }
+ SkIRect dstRect = SkIRect::MakeSize(backendTexture.dimensions());
+ this->uploadTextureData(colorType, texels.get(), numMipLevels, dstRect, info.fTexture);
+ return true;
+ }
+ pixels = defaultStorage.get();
GrColorType colorType;
if (!GrDawnFormatToGrColorType(info.fFormat, &colorType)) {
return false;
}
-
- size_t bpp = GrDawnBytesPerBlock(info.fFormat);
- size_t baseLayerSize = bpp * backendTexture.width() * backendTexture.height();
- SkAutoMalloc defaultStorage(baseLayerSize);
- GrImageInfo imageInfo(colorType, kUnpremul_SkAlphaType, nullptr, backendTexture.dimensions());
- GrClearImage(imageInfo, defaultStorage.get(), bpp * backendTexture.width(), color);
-
+ SkISize size{backendTexture.width(), backendTexture.height()};
+ GrImageInfo imageInfo(colorType, kUnpremul_SkAlphaType, nullptr, size);
+ GrClearImage(imageInfo, defaultStorage.get(), bpp * backendTexture.width(), data->color());
wgpu::Device device = this->device();
wgpu::CommandEncoder copyEncoder = this->getCopyEncoder();
int w = backendTexture.width(), h = backendTexture.height();
@@ -409,9 +421,9 @@
GrStagingBufferManager::Slice stagingBuffer =
this->stagingBufferManager()->allocateStagingBufferSlice(size);
if (rowBytes == origRowBytes) {
- memcpy(stagingBuffer.fOffsetMapPtr, defaultStorage.get(), size);
+ memcpy(stagingBuffer.fOffsetMapPtr, pixels, size);
} else {
- const char* src = static_cast<const char*>(defaultStorage.get());
+ const char* src = static_cast<const char*>(pixels);
char* dst = static_cast<char*>(stagingBuffer.fOffsetMapPtr);
for (int row = 0; row < h; row++) {
memcpy(dst, src, origRowBytes);
@@ -443,8 +455,7 @@
bool GrDawnGpu::onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) {
+ const BackendTextureData*) {
return false;
}
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index f1b34b4..5959a16 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -144,9 +144,9 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override;
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override;
GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
const GrBackendFormat&,
@@ -155,8 +155,7 @@
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) override;
+ const BackendTextureData*) override;
sk_sp<GrGpuBuffer> 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 bf1f3d9..8e1e5fd 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -980,7 +980,7 @@
bool GrGLGpu::uploadColorToTex(GrGLFormat textureFormat,
SkISize texDims,
GrGLenum target,
- std::array<float, 4> color,
+ SkColor4f color,
uint32_t levelMask) {
GrColorType colorType;
GrGLenum externalFormat, externalType;
@@ -1386,11 +1386,8 @@
fHWBoundRenderTargetUniqueID.makeInvalid();
} else {
this->bindTextureToScratchUnit(texDesc.fTarget, tex->textureID());
- std::array<float, 4> zeros = {};
- this->uploadColorToTex(texDesc.fFormat,
- texDesc.fSize,
- texDesc.fTarget,
- zeros,
+ static constexpr SkColor4f kZeroColor = {0, 0, 0, 0};
+ this->uploadColorToTex(texDesc.fFormat, texDesc.fSize, texDesc.fTarget, kZeroColor,
levelClearMask);
}
}
@@ -1485,8 +1482,11 @@
bool GrGLGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length) {
+ const BackendTextureData* data) {
+ SkASSERT(data && data->type() != BackendTextureData::Type::kPixmaps);
+
+ this->handleDirtyContext();
+
GrGLTextureInfo info;
SkAssertResult(backendTexture.getGLTextureInfo(&info));
@@ -1499,6 +1499,27 @@
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);
// If we have mips make sure the base level is set to 0 and the max level set to numMipLevels-1
@@ -1519,13 +1540,9 @@
params->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
}
- bool result = this->uploadCompressedTexData(compression,
- glFormat,
- backendTexture.dimensions(),
- mipMapped,
- GR_GL_TEXTURE_2D,
- data,
- length);
+ 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);
@@ -3601,9 +3618,9 @@
std::move(parameters));
}
-bool GrGLGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrGLGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
this->handleDirtyContext();
GrGLTextureInfo info;
@@ -3635,12 +3652,26 @@
params->set(nullptr, nonsamplerState, fResetTimestampForTextureParameters);
}
- uint32_t levelMask = (1 << numMipLevels) - 1;
- bool result = this->uploadColorToTex(glFormat,
- backendTexture.dimensions(),
- info.fTarget,
- color,
- levelMask);
+ SkASSERT(data->type() != BackendTextureData::Type::kCompressed);
+ bool result = false;
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ SkTArray<GrMipLevel> texels;
+ texels.push_back_n(numMipLevels);
+ GrColorType colorType = data->pixmap(0).colorType();
+ for (int i = 0; i < numMipLevels; ++i) {
+ texels[i] = {data->pixmap(i).addr(),
+ data->pixmap(i).rowBytes(),
+ data->pixmap(i).pixelStorage()};
+ }
+ SkIRect dstRect = SkIRect::MakeSize(backendTexture.dimensions());
+ result = this->uploadColorTypeTexData(glFormat, colorType, backendTexture.dimensions(),
+ info.fTarget, dstRect, colorType, texels.begin(),
+ texels.count());
+ } else if (data->type() == BackendTextureData::Type::kColor) {
+ uint32_t levelMask = (1 << numMipLevels) - 1;
+ result = this->uploadColorToTex(glFormat, backendTexture.dimensions(), info.fTarget,
+ data->color(), levelMask);
+ }
// Unbind this texture from the scratch texture unit.
this->bindTextureToScratchUnit(info.fTarget, 0);
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 9494930..0a47a9d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -212,14 +212,13 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override;
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override;
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length) override;
+ const BackendTextureData*) override;
void onResetContext(uint32_t resetBits) override;
@@ -455,7 +454,7 @@
bool uploadColorToTex(GrGLFormat textureFormat,
SkISize texDims,
GrGLenum target,
- std::array<float, 4> color,
+ SkColor4f color,
uint32_t levelMask);
// Pushes data to the currently bound texture to the currently active unit. 'dstRect' must be
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 05064a1..085191f 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -165,9 +165,9 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override {
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override {
return true;
}
@@ -178,8 +178,7 @@
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void*,
- size_t) override {
+ const BackendTextureData*) override {
return true;
}
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 4502050..5370da2 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -131,9 +131,9 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override;
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override;
GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
const GrBackendFormat&,
@@ -142,8 +142,7 @@
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) override;
+ const BackendTextureData*) override;
sk_sp<GrTexture> onCreateTexture(SkISize,
const GrBackendFormat&,
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index b43d7a6..3c4fbff 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -946,9 +946,9 @@
return backendTex;
}
-bool GrMtlGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrMtlGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
GrMtlTextureInfo info;
SkAssertResult(backendTexture.getMtlTextureInfo(&info));
@@ -956,19 +956,45 @@
const MTLPixelFormat mtlFormat = mtlTexture.pixelFormat;
+ int numMipLevels = mtlTexture.mipmapLevelCount;
+ GrMipmapped mipMapped = numMipLevels > 1 ? GrMipmapped::kYes : GrMipmapped::kNo;
+
+ SkImage::CompressionType compression = GrBackendFormatToCompressionType(
+ backendTexture.getBackendFormat());
+
// Create a transfer buffer and fill with data.
size_t bytesPerPixel = GrMtlFormatBytesPerBlock(mtlFormat);
+ SkSTArray<16, size_t> individualMipOffsets;
size_t combinedBufferSize;
- // Reuse the same buffer for all levels. Should be ok since we made the row bytes tight.
- combinedBufferSize = bytesPerPixel*backendTexture.width()*backendTexture.height();
+ if (data->type() == BackendTextureData::Type::kColor &&
+ compression == SkImage::CompressionType::kNone) {
+ combinedBufferSize = bytesPerPixel*backendTexture.width()*backendTexture.height();
+ // Reuse the same buffer for all levels. Should be ok since we made the row bytes tight.
+ individualMipOffsets.push_back_n(numMipLevels, (size_t)0);
+ } else if (compression == SkImage::CompressionType::kNone) {
+ combinedBufferSize = GrComputeTightCombinedBufferSize(bytesPerPixel,
+ backendTexture.dimensions(),
+ &individualMipOffsets,
+ numMipLevels);
+ } else {
+ combinedBufferSize = SkCompressedDataSize(compression, backendTexture.dimensions(),
+ &individualMipOffsets,
+ mipMapped == GrMipmapped::kYes);
+ }
+ SkASSERT(individualMipOffsets.count() == numMipLevels);
#ifdef SK_BUILD_FOR_MAC
static const size_t kMinAlignment = 4;
#else
static const size_t kMinAlignment = 1;
#endif
- size_t alignment = std::max(bytesPerPixel, kMinAlignment);
+ size_t alignment;
+ if (data->type() == BackendTextureData::Type::kCompressed) {
+ alignment = std::max(SkCompressedBlockSize(compression), kMinAlignment);
+ } else {
+ alignment = std::max(bytesPerPixel, kMinAlignment);
+ }
GrStagingBufferManager::Slice slice = fStagingBufferManager.allocateStagingBufferSlice(
combinedBufferSize, alignment);
if (!slice.fBuffer) {
@@ -976,15 +1002,28 @@
}
char* buffer = (char*)slice.fOffsetMapPtr;
- auto colorType = mtl_format_to_backend_tex_clear_colortype(mtlFormat);
- if (colorType == GrColorType::kUnknown) {
- return false;
- }
- GrImageInfo ii(colorType, kUnpremul_SkAlphaType, nullptr, backendTexture.dimensions());
- auto rb = ii.minRowBytes();
- SkASSERT(rb == bytesPerPixel*backendTexture.width());
- if (!GrClearImage(ii, buffer, rb, color)) {
- return false;
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ copy_src_data(buffer, bytesPerPixel, individualMipOffsets, data->pixmaps(),
+ numMipLevels, combinedBufferSize);
+ } else if (data->type() == BackendTextureData::Type::kCompressed) {
+ memcpy(buffer, data->compressedData(), data->compressedSize());
+ } else {
+ SkASSERT(data->type() == BackendTextureData::Type::kColor);
+ if (compression == SkImage::CompressionType::kNone) {
+ auto colorType = mtl_format_to_backend_tex_clear_colortype(mtlFormat);
+ if (colorType == GrColorType::kUnknown) {
+ return false;
+ }
+ GrImageInfo ii(colorType, kUnpremul_SkAlphaType, nullptr, backendTexture.dimensions());
+ auto rb = ii.minRowBytes();
+ SkASSERT(rb == bytesPerPixel*backendTexture.width());
+ if (!GrClearImage(ii, buffer, rb, data->color())) {
+ return false;
+ }
+ } else {
+ GrFillInCompressedData(compression, backendTexture.dimensions(), mipMapped, buffer,
+ data->color());
+ }
}
// Transfer buffer contents to texture
@@ -995,29 +1034,32 @@
GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);
SkISize levelDimensions(backendTexture.dimensions());
- int numMipLevels = mtlTexture.mipmapLevelCount;
for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
size_t levelRowBytes;
size_t levelSize;
- levelRowBytes = levelDimensions.width() * bytesPerPixel;
- levelSize = levelRowBytes * levelDimensions.height();
+ if (compression == SkImage::CompressionType::kNone) {
+ levelRowBytes = levelDimensions.width() * bytesPerPixel;
+ levelSize = levelRowBytes * levelDimensions.height();
+ } else {
+ levelRowBytes = GrCompressedRowBytes(compression, levelDimensions.width());
+ levelSize = SkCompressedDataSize(compression, levelDimensions, nullptr, false);
+ }
// TODO: can this all be done in one go?
[blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
- sourceOffset: slice.fOffset
+ sourceOffset: slice.fOffset + individualMipOffsets[currentMipLevel]
sourceBytesPerRow: levelRowBytes
sourceBytesPerImage: levelSize
sourceSize: MTLSizeMake(levelDimensions.width(),
- levelDimensions.height(),
- 1)
+ levelDimensions.height(), 1)
toTexture: mtlTexture
destinationSlice: 0
destinationLevel: currentMipLevel
destinationOrigin: origin];
- levelDimensions = {std::max(1, levelDimensions.width() / 2),
- std::max(1, levelDimensions.height() / 2)};
+ levelDimensions = { std::max(1, levelDimensions.width() / 2),
+ std::max(1, levelDimensions.height() / 2) };
}
#ifdef SK_BUILD_FOR_MAC
[mtlBuffer->mtlBuffer() didModifyRange: NSMakeRange(slice.fOffset, combinedBufferSize)];
@@ -1046,84 +1088,8 @@
bool GrMtlGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) {
- GrMtlTextureInfo info;
- SkAssertResult(backendTexture.getMtlTextureInfo(&info));
-
- id<MTLTexture> mtlTexture = GrGetMTLTexture(info.fTexture.get());
-
- int numMipLevels = mtlTexture.mipmapLevelCount;
- GrMipmapped mipMapped = numMipLevels > 1 ? GrMipmapped::kYes : GrMipmapped::kNo;
-
- SkImage::CompressionType compression =
- GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
- SkASSERT(compression != SkImage::CompressionType::kNone);
-
- // Create a transfer buffer and fill with data.
- SkSTArray<16, size_t> individualMipOffsets;
- size_t combinedBufferSize;
- combinedBufferSize = SkCompressedDataSize(compression,
- backendTexture.dimensions(),
- &individualMipOffsets,
- mipMapped == GrMipmapped::kYes);
- SkASSERT(individualMipOffsets.count() == numMipLevels);
-
-#ifdef SK_BUILD_FOR_MAC
- static const size_t kMinAlignment = 4;
-#else
- static const size_t kMinAlignment = 1;
-#endif
- size_t alignment = std::max(SkCompressedBlockSize(compression), kMinAlignment);
- GrStagingBufferManager::Slice slice =
- fStagingBufferManager.allocateStagingBufferSlice(combinedBufferSize, alignment);
- if (!slice.fBuffer) {
- return false;
- }
- char* buffer = (char*)slice.fOffsetMapPtr;
-
- memcpy(buffer, data, size);
-
- // Transfer buffer contents to texture
- MTLOrigin origin = MTLOriginMake(0, 0, 0);
-
- GrMtlCommandBuffer* cmdBuffer = this->commandBuffer();
- id<MTLBlitCommandEncoder> blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
- GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);
-
- SkISize levelDimensions(backendTexture.dimensions());
- for (int currentMipLevel = 0; currentMipLevel < numMipLevels; currentMipLevel++) {
- size_t levelRowBytes;
- size_t levelSize;
-
- levelRowBytes = GrCompressedRowBytes(compression, levelDimensions.width());
- levelSize = SkCompressedDataSize(compression, levelDimensions, nullptr, false);
-
- // TODO: can this all be done in one go?
- [blitCmdEncoder copyFromBuffer: mtlBuffer->mtlBuffer()
- sourceOffset: slice.fOffset + individualMipOffsets[currentMipLevel]
- sourceBytesPerRow: levelRowBytes
- sourceBytesPerImage: levelSize
- sourceSize: MTLSizeMake(levelDimensions.width(),
- levelDimensions.height(),
- 1)
- toTexture: mtlTexture
- destinationSlice: 0
- destinationLevel: currentMipLevel
- destinationOrigin: origin];
-
- levelDimensions = {std::max(1, levelDimensions.width() / 2),
- std::max(1, levelDimensions.height() / 2)};
- }
-#ifdef SK_BUILD_FOR_MAC
- [mtlBuffer->mtlBuffer() didModifyRange:NSMakeRange(slice.fOffset, combinedBufferSize)];
-#endif
-
- if (finishedCallback) {
- this->addFinishedCallback(std::move(finishedCallback));
- }
-
- return true;
+ 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 f5285b5..1e5655d 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -729,17 +729,14 @@
// This fills in the 'regions' vector in preparation for copying a buffer to an image.
// 'individualMipOffsets' is filled in as a side-effect.
-static size_t fill_in_compressed_regions(GrStagingBufferManager* stagingBufferManager,
- SkTArray<VkBufferImageCopy>* regions,
- SkTArray<size_t>* individualMipOffsets,
- GrStagingBufferManager::Slice* slice,
- SkImage::CompressionType compression,
- VkFormat vkFormat,
- SkISize dimensions,
- GrMipmapped mipmapped) {
- SkASSERT(compression != SkImage::CompressionType::kNone);
+static size_t fill_in_regions(GrStagingBufferManager* stagingBufferManager,
+ SkTArray<VkBufferImageCopy>* regions,
+ SkTArray<size_t>* individualMipOffsets,
+ GrStagingBufferManager::Slice* slice,
+ SkImage::CompressionType compression,
+ VkFormat vkFormat, SkISize dimensions, GrMipmapped mipMapped) {
int numMipLevels = 1;
- if (mipmapped == GrMipmapped::kYes) {
+ if (mipMapped == GrMipmapped::kYes) {
numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
}
@@ -748,10 +745,15 @@
size_t bytesPerBlock = GrVkFormatBytesPerBlock(vkFormat);
- size_t bufferSize = SkCompressedDataSize(compression,
- dimensions,
- individualMipOffsets,
- mipmapped == GrMipmapped::kYes);
+ size_t combinedBufferSize;
+ if (compression == SkImage::CompressionType::kNone) {
+ combinedBufferSize = GrComputeTightCombinedBufferSize(bytesPerBlock, dimensions,
+ individualMipOffsets,
+ numMipLevels);
+ } else {
+ combinedBufferSize = SkCompressedDataSize(compression, dimensions, individualMipOffsets,
+ mipMapped == GrMipmapped::kYes);
+ }
SkASSERT(individualMipOffsets->count() == numMipLevels);
// Get a staging buffer slice to hold our mip data.
@@ -762,7 +764,7 @@
case 2: alignment *= 2; break; // alignment is a multiple of 2 but not 4.
default: alignment *= 4; break; // alignment is not a multiple of 2.
}
- *slice = stagingBufferManager->allocateStagingBufferSlice(bufferSize, alignment);
+ *slice = stagingBufferManager->allocateStagingBufferSlice(combinedBufferSize, alignment);
if (!slice->fBuffer) {
return 0;
}
@@ -783,7 +785,7 @@
std::max(1, dimensions.height()/2)};
}
- return bufferSize;
+ return combinedBufferSize;
}
bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment, int left, int top, int width,
@@ -931,14 +933,10 @@
GrStagingBufferManager::Slice slice;
SkTArray<VkBufferImageCopy> regions;
SkTArray<size_t> individualMipOffsets;
- SkDEBUGCODE(size_t combinedBufferSize =) fill_in_compressed_regions(&fStagingBufferManager,
- ®ions,
- &individualMipOffsets,
- &slice,
- compression,
- vkFormat,
- dimensions,
- mipMapped);
+ SkDEBUGCODE(size_t combinedBufferSize =) fill_in_regions(&fStagingBufferManager,
+ ®ions, &individualMipOffsets,
+ &slice, compression, vkFormat,
+ dimensions, mipMapped);
if (!slice.fBuffer) {
return false;
}
@@ -1464,6 +1462,22 @@
return true;
}
+bool copy_compressed_data(GrVkGpu* gpu, char* mapPtr,
+ const void* rawData, size_t dataSize) {
+ SkASSERT(mapPtr);
+ memcpy(mapPtr, rawData, dataSize);
+ return true;
+}
+
+bool generate_compressed_data(GrVkGpu* gpu, char* mapPtr,
+ SkImage::CompressionType compression, SkISize dimensions,
+ GrMipmapped mipMapped, const SkColor4f& color) {
+ SkASSERT(mapPtr);
+ GrFillInCompressedData(compression, dimensions, mipMapped, mapPtr, color);
+
+ return true;
+}
+
bool GrVkGpu::createVkImageForBackendSurface(VkFormat vkFormat,
SkISize dimensions,
int sampleCnt,
@@ -1531,9 +1545,9 @@
return true;
}
-bool GrVkGpu::onClearBackendTexture(const GrBackendTexture& backendTexture,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) {
+bool GrVkGpu::onUpdateBackendTexture(const GrBackendTexture& backendTexture,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData* data) {
GrVkImageInfo info;
SkAssertResult(backendTexture.getVkImageInfo(&info));
@@ -1557,23 +1571,68 @@
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
false);
- // CmdClearColorImage doesn't work for compressed formats
- SkASSERT(!GrVkFormatIsCompressed(info.fFormat));
+ // Unfortunately, CmdClearColorImage doesn't work for compressed formats
+ bool fastPath = data->type() == BackendTextureData::Type::kColor &&
+ !GrVkFormatIsCompressed(info.fFormat);
- VkClearColorValue vkColor;
- // If we ever support SINT or UINT formats this needs to be updated to use the int32 and
- // uint32 union members in those cases.
- vkColor.float32[0] = color[0];
- vkColor.float32[1] = color[1];
- vkColor.float32[2] = color[2];
- vkColor.float32[3] = color[3];
- VkImageSubresourceRange range;
- range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- range.baseArrayLayer = 0;
- range.baseMipLevel = 0;
- range.layerCount = 1;
- range.levelCount = info.fLevelCount;
- cmdBuffer->clearColorImage(this, texAttachment, &vkColor, 1, &range);
+ if (fastPath) {
+ SkASSERT(data->type() == BackendTextureData::Type::kColor);
+ VkClearColorValue vkColor;
+ SkColor4f color = data->color();
+ // If we ever support SINT or UINT formats this needs to be updated to use the int32 and
+ // uint32 union members in those cases.
+ vkColor.float32[0] = color.fR;
+ vkColor.float32[1] = color.fG;
+ vkColor.float32[2] = color.fB;
+ vkColor.float32[3] = color.fA;
+ VkImageSubresourceRange range;
+ range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ range.baseArrayLayer = 0;
+ range.baseMipLevel = 0;
+ range.layerCount = 1;
+ range.levelCount = info.fLevelCount;
+ cmdBuffer->clearColorImage(this, texAttachment, &vkColor, 1, &range);
+ } else {
+ SkImage::CompressionType compression = GrBackendFormatToCompressionType(
+ backendTexture.getBackendFormat());
+
+ SkTArray<VkBufferImageCopy> regions;
+ SkTArray<size_t> individualMipOffsets;
+ GrStagingBufferManager::Slice slice;
+
+ fill_in_regions(&fStagingBufferManager, ®ions, &individualMipOffsets,
+ &slice, compression, info.fFormat, backendTexture.dimensions(),
+ backendTexture.fMipmapped);
+
+ if (!slice.fBuffer) {
+ return false;
+ }
+
+ bool result;
+ if (data->type() == BackendTextureData::Type::kPixmaps) {
+ result = copy_src_data((char*)slice.fOffsetMapPtr, info.fFormat, individualMipOffsets,
+ data->pixmaps(), info.fLevelCount);
+ } else if (data->type() == BackendTextureData::Type::kCompressed) {
+ result = copy_compressed_data(this, (char*)slice.fOffsetMapPtr,
+ data->compressedData(), data->compressedSize());
+ } else {
+ SkASSERT(data->type() == BackendTextureData::Type::kColor);
+ result = generate_compressed_data(this, (char*)slice.fOffsetMapPtr, compression,
+ backendTexture.dimensions(),
+ backendTexture.fMipmapped, data->color());
+ }
+
+ cmdBuffer->addGrSurface(texture);
+ // Copy the buffer to the image. This call takes the raw VkBuffer instead of a GrGpuBuffer
+ // because we don't need the command buffer to ref the buffer here. The reason being is that
+ // the buffer is coming from the staging manager and the staging manager will make sure the
+ // command buffer has a ref on the buffer. This avoids having to add and remove a ref for
+ // every upload in the frame.
+ const GrVkBuffer* vkBuffer = static_cast<GrVkBuffer*>(slice.fBuffer);
+ cmdBuffer->copyBufferToImage(this, vkBuffer->vkBuffer(), texAttachment,
+ texAttachment->currentLayout(), regions.count(),
+ regions.begin());
+ }
// Change image layout to shader read since if we use this texture as a borrowed
// texture within Ganesh we require that its layout be set to that
@@ -1630,82 +1689,8 @@
bool GrVkGpu::onUpdateCompressedBackendTexture(const GrBackendTexture& backendTexture,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t size) {
- GrVkImageInfo info;
- SkAssertResult(backendTexture.getVkImageInfo(&info));
-
- sk_sp<GrBackendSurfaceMutableStateImpl> mutableState = backendTexture.getMutableState();
- SkASSERT(mutableState);
- sk_sp<GrVkTexture> texture = GrVkTexture::MakeWrappedTexture(this,
- backendTexture.dimensions(),
- kBorrow_GrWrapOwnership,
- GrWrapCacheable::kNo,
- kRW_GrIOType,
- info,
- std::move(mutableState));
- if (!texture) {
- return false;
- }
-
- GrVkPrimaryCommandBuffer* cmdBuffer = this->currentCommandBuffer();
- if (!cmdBuffer) {
- return false;
- }
- GrVkAttachment* attachment = texture->textureAttachment();
- attachment->setImageLayout(this,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_ACCESS_TRANSFER_WRITE_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- false);
-
- SkImage::CompressionType compression =
- GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
-
- SkTArray<VkBufferImageCopy> regions;
- SkTArray<size_t> individualMipOffsets;
- GrStagingBufferManager::Slice slice;
-
- fill_in_compressed_regions(&fStagingBufferManager,
- ®ions,
- &individualMipOffsets,
- &slice,
- compression,
- info.fFormat,
- backendTexture.dimensions(),
- backendTexture.fMipmapped);
-
- if (!slice.fBuffer) {
- return false;
- }
-
- memcpy(slice.fOffsetMapPtr, data, size);
-
- cmdBuffer->addGrSurface(texture);
- // Copy the buffer to the image. This call takes the raw VkBuffer instead of a GrGpuBuffer
- // because we don't need the command buffer to ref the buffer here. The reason being is that
- // the buffer is coming from the staging manager and the staging manager will make sure the
- // command buffer has a ref on the buffer. This avoids having to add and remove a ref for
- // every upload in the frame.
- cmdBuffer->copyBufferToImage(this,
- static_cast<GrVkBuffer*>(slice.fBuffer)->vkBuffer(),
- attachment,
- attachment->currentLayout(),
- regions.count(),
- regions.begin());
-
- // Change image layout to shader read since if we use this texture as a borrowed
- // texture within Ganesh we require that its layout be set to that
- attachment->setImageLayout(this,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- VK_ACCESS_SHADER_READ_BIT,
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
- false);
-
- if (finishedCallback) {
- this->addFinishedCallback(std::move(finishedCallback));
- }
- return true;
+ 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 8dbc3c9..d4070ec 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -218,14 +218,13 @@
GrMipmapped,
GrProtected) override;
- bool onClearBackendTexture(const GrBackendTexture&,
- sk_sp<GrRefCntedCallback> finishedCallback,
- std::array<float, 4> color) override;
+ bool onUpdateBackendTexture(const GrBackendTexture&,
+ sk_sp<GrRefCntedCallback> finishedCallback,
+ const BackendTextureData*) override;
bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
sk_sp<GrRefCntedCallback> finishedCallback,
- const void* data,
- size_t length) override;
+ const BackendTextureData*) override;
bool setBackendSurfaceState(GrVkImageInfo info,
sk_sp<GrBackendSurfaceMutableStateImpl> currentState,
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index 75a68de..e504f9d 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -222,7 +222,7 @@
static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct) {
GrImageInfo ii(ct, kUnpremul_SkAlphaType, nullptr, {1, 1});
std::unique_ptr<char[]> data(new char[ii.minRowBytes()]);
- GrClearImage(ii, data.get(), ii.minRowBytes(), orig.array());
+ GrClearImage(ii, data.get(), ii.minRowBytes(), orig);
// Read back to SkColor4f.
SkColor4f result;