Revert "Move ExternalFormat and Type to FormatInfo."

This reverts commit 80140518ef.

Reason for revert: probably breaking angle

Original change's description:
> Move ExternalFormat and Type to FormatInfo.
> 
> This also deletes the ConfigInfoTable in GrGLCaps as there is no more use
> of it.
> 
> Additionally with the rework of storing External Io info on the format table
> I rewrote the implimination of supportedReadPixels and supportedWritePixels
> for GL to loop over the supported types looking for a match instead of
> simply defaulting to a base value.
> 
> Finally transferFromOffsetAlignment has been rolled into the SupportedRead
> instead of being its own query.
> 
> Bug: skia:6718
> Change-Id: I39f77adf6c0b5b38245e55e8a7e18c0b428862d0
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/229381
> Commit-Queue: Greg Daniel <egdaniel@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>

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

Change-Id: Ifef2e7308fdb4d91d649f08488b798815e0aa5fa
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:6718
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/229896
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2019-07-25 18:46:39 +00:00 committed by Skia Commit-Bot
parent f27e51f8a7
commit e2c5e8c7ee
17 changed files with 712 additions and 1072 deletions

View File

@ -296,6 +296,32 @@ bool GrCaps::surfaceSupportsWritePixels(const GrSurface* surface) const {
return surface->readOnly() ? false : this->onSurfaceSupportsWritePixels(surface);
}
size_t GrCaps::transferFromOffsetAlignment(GrColorType bufferColorType) const {
if (!this->transferBufferSupport()) {
return 0;
}
size_t result = this->onTransferFromOffsetAlignment(bufferColorType);
if (!result) {
return 0;
}
// It's very convenient to access 1 byte-per-channel 32 bitvRGB/RGBA color types as uint32_t.
// Make those aligned reads out of the buffer even if the underlying API doesn't require it.
auto componentFlags = GrColorTypeComponentFlags(bufferColorType);
if ((componentFlags == kRGBA_SkColorTypeComponentFlags ||
componentFlags == kRGB_SkColorTypeComponentFlags) &&
GrColorTypeBytesPerPixel(bufferColorType) == 4) {
switch (result & 0b11) {
// offset alignment already a multiple of 4
case 0: return result;
// offset alignment is a multiple of 2 but not 4.
case 2: return 2 * result;
// offset alignment is not a multiple of 2.
default: return 4 * result;
}
}
return result;
}
bool GrCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const {
if (dst->readOnly()) {
@ -351,35 +377,9 @@ bool GrCaps::validateSurfaceDesc(const GrSurfaceDesc& desc, GrRenderable rendera
}
GrCaps::SupportedRead GrCaps::supportedReadPixelsColorType(GrColorType srcColorType,
const GrBackendFormat& srcFormat,
const GrBackendFormat&,
GrColorType dstColorType) const {
SupportedRead read = this->onSupportedReadPixelsColorType(srcColorType, srcFormat,
dstColorType);
// There are known problems with 24 vs 32 bit BPP with this color type. Just fail for now if
// using a transfer buffer.
if (GrColorType::kRGB_888x == read.fColorType) {
read.fOffsetAlignmentForTransferBuffer = 0;
}
// It's very convenient to access 1 byte-per-channel 32 bitvRGB/RGBA color types as uint32_t.
// Make those aligned reads out of the buffer even if the underlying API doesn't require it.
auto componentFlags = GrColorTypeComponentFlags(read.fColorType);
if ((componentFlags == kRGBA_SkColorTypeComponentFlags ||
componentFlags == kRGB_SkColorTypeComponentFlags) &&
GrColorTypeBytesPerPixel(read.fColorType) == 4) {
switch (read.fOffsetAlignmentForTransferBuffer & 0b11) {
// offset alignment already a multiple of 4
case 0:
break;
// offset alignment is a multiple of 2 but not 4.
case 2:
read.fOffsetAlignmentForTransferBuffer *= 2;
// offset alignment is not a multiple of 2.
default:
read.fOffsetAlignmentForTransferBuffer *= 4;
}
}
return read;
return SupportedRead{GrSwizzle::RGBA(), srcColorType};
}
#ifdef SK_DEBUG

View File

@ -234,7 +234,6 @@ public:
struct SupportedRead {
GrSwizzle fSwizzle;
GrColorType fColorType;
size_t fOffsetAlignmentForTransferBuffer;
};
/**
@ -245,9 +244,9 @@ public:
* to dstColorType the swizzle in the returned struct should be applied. The caller must check
* the returned color type for kUnknown.
*/
SupportedRead supportedReadPixelsColorType(GrColorType srcColorType,
const GrBackendFormat& srcFormat,
GrColorType dstColorType) const;
virtual SupportedRead supportedReadPixelsColorType(GrColorType srcColorType,
const GrBackendFormat& srcFormat,
GrColorType dstColorType) const;
/**
* Do GrGpu::writePixels() and GrGpu::transferPixelsTo() support a src buffer where the row
@ -262,6 +261,18 @@ public:
/** Are transfer buffers (to textures and from surfaces) supported? */
bool transferBufferSupport() const { return fTransferBufferSupport; }
/**
* Gets the alignment requirement for the buffer offset used with GrGpu::transferPixelsFrom for
* a given GrColorType. To check whether a pixels as GrColorType can be read for a given surface
* see supportedReadPixelsColorType() and surfaceSupportsReadPixels().
*
* @param bufferColorType The color type of the pixel data that will be stored in the transfer
* buffer.
* @return minimum required alignment for the buffer offset or zero if reading to the color type
* is not supported.
*/
size_t transferFromOffsetAlignment(GrColorType bufferColorType) const;
bool suppressPrints() const { return fSuppressPrints; }
size_t bufferMapThreshold() const {
@ -520,6 +531,7 @@ private:
virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0;
virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0;
virtual size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const = 0;
// Backends should implement this if they have any extra requirements for use of window
// rectangles for a specific GrBackendRenderTarget outside of basic support.
@ -532,10 +544,6 @@ private:
virtual bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const = 0;
virtual SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType,
const GrBackendFormat& srcFormat,
GrColorType dstColorType) const = 0;
bool fSuppressPrints : 1;
bool fWireframeMode : 1;

View File

@ -465,14 +465,8 @@ bool GrGpu::transferPixelsFrom(GrSurface* surface, int left, int top, int width,
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkASSERT(surface);
SkASSERT(transferBuffer);
#ifdef SK_DEBUG
GrColorType surfCT = GrPixelConfigToColorType(surface->config());
auto supportedRead = this->caps()->supportedReadPixelsColorType(surfCT,
surface->backendFormat(),
bufferColorType);
SkASSERT(supportedRead.fOffsetAlignmentForTransferBuffer);
SkASSERT(offset % supportedRead.fOffsetAlignmentForTransferBuffer == 0);
#endif
SkASSERT(this->caps()->transferFromOffsetAlignment(bufferColorType));
SkASSERT(offset % this->caps()->transferFromOffsetAlignment(bufferColorType) == 0);
// We require that the write region is contained in the texture
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);

View File

@ -256,8 +256,8 @@ public:
/**
* Reads the pixels from a rectangle of a surface into a buffer. Use
* GrCaps::SupportedRead::fOffsetAlignmentForTransferBuffer to determine the requirements for
* the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read.
* GrCaps::transferFromOffsetAlignment to determine the requirements for the buffer offset
* alignment. If the surface is a MIP mapped texture, the base level is read.
*
* If successful the row bytes in the buffer is always:
* GrColorTypeBytesPerPixel(bufferColorType) * width

View File

@ -1688,7 +1688,7 @@ GrRenderTargetContext::PixelTransferResult GrRenderTargetContext::transferPixels
}
if (!this->caps()->transferBufferSupport() ||
!supportedRead.fOffsetAlignmentForTransferBuffer) {
!this->caps()->transferFromOffsetAlignment(supportedRead.fColorType)) {
return {};
}

File diff suppressed because it is too large Load Diff

View File

@ -169,18 +169,15 @@ public:
return this->getSizedInternalFormat(this->pixelConfigToFormat(config));
}
// TODO: Once pixel config is no longer used in the caps remove this helper function.
GrGLFormat pixelConfigToFormat(GrPixelConfig) const;
void getTexImageFormats(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
GrColorType memoryColorType, GrGLenum* internalFormat,
GrGLenum* externalFormat, GrGLenum* externalType) const;
bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
GrGLenum* internalFormat, GrGLenum* externalFormat,
GrGLenum* externalType) const;
bool getCompressedTexImageFormats(GrPixelConfig surfaceConfig, GrGLenum* internalFormat) const;
void getReadPixelsFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
GrColorType memoryColorType, GrGLenum* externalFormat,
GrGLenum* externalType) const;
bool getReadPixelsFormat(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig,
GrGLenum* externalFormat, GrGLenum* externalType) const;
/**
* Gets an array of legal stencil formats. These formats are not guaranteed
@ -349,11 +346,8 @@ public:
bool useNonVBOVertexAndIndexDynamicData() const { return fUseNonVBOVertexAndIndexDynamicData; }
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
GrColorType supportedWritePixelsColorType(GrPixelConfig config,
GrColorType srcColorType) const override;
SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
bool isCoreProfile() const { return fIsCoreProfile; }
@ -468,10 +462,13 @@ private:
enum ExternalFormatUsage {
kTexImage_ExternalFormatUsage,
kReadPixels_ExternalFormatUsage,
kLast_ExternalFormatUsage = kReadPixels_ExternalFormatUsage
};
void getExternalFormat(GrGLFormat surfaceFormat, GrColorType surfaceColorType,
GrColorType memoryColorType, ExternalFormatUsage usage,
GrGLenum* externalFormat, GrGLenum* externalType) const;
static const int kExternalFormatUsageCnt = kLast_ExternalFormatUsage + 1;
bool getExternalFormat(GrPixelConfig surfaceConfig, GrPixelConfig memoryConfig,
ExternalFormatUsage usage, GrGLenum* externalFormat,
GrGLenum* externalType) const;
void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
void initGLSL(const GrGLContextInfo&, const GrGLInterface*);
@ -499,11 +496,13 @@ private:
void initBlendEqationSupport(const GrGLContextInfo&);
void initStencilSupport(const GrGLContextInfo&);
// This must be called after initFSAASupport().
void initConfigTable(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
void initFormatTable(const GrGLContextInfo&, const GrGLInterface*, const FormatWorkarounds&);
void setupSampleCounts(const GrGLContextInfo&, const GrGLInterface*);
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const override;
GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;
@ -513,6 +512,9 @@ private:
int getRenderTargetSampleCount(int requestedCount, GrColorType, GrGLFormat) const;
int maxRenderTargetSampleCount(GrColorType, GrGLFormat) const;
// TODO: Once pixel config is no longer used in the caps remove this helper function.
GrGLFormat pixelConfigToFormat(GrPixelConfig) const;
GrGLStandard fStandard;
SkTArray<StencilFormat, true> fStencilFormats;
@ -578,10 +580,23 @@ private:
memset(this, 0xAB, sizeof(ConfigFormats));
}
/** The external format and type are to be used when uploading/downloading data using this
config where both the CPU data and GrSurface are the same config. To get the external
format and type when converting between configs while copying to/from memory use
getExternalFormat().
The kTexImage external format is usually the same as kOther except for kSRGBA on some
GL contexts. */
GrGLenum fExternalFormat[kExternalFormatUsageCnt];
GrGLenum fExternalType;
};
struct ConfigInfo {
ConfigFormats fFormats;
// On ES contexts there are restrictions on type type/format that may be used for
// ReadPixels. One is implicitly specified by the current FBO's format. The other is
// queryable. This stores the queried option (lazily).
ReadPixelsFormat fSecondReadPixelsFormat;
};
ConfigInfo fConfigTable[kGrPixelConfigCnt];
@ -595,63 +610,33 @@ private:
// ColorTypeInfo for a specific format
struct ColorTypeInfo {
GrColorType fColorType = GrColorType::kUnknown;
ColorTypeInfo(GrColorType colorType, uint32_t flags)
: fColorType(colorType)
, fFlags(flags) {}
ColorTypeInfo(GrColorType colorType, uint32_t flags, GrSwizzle rgbaReadSwizzle)
: fColorType(colorType)
, fFlags(flags)
, fRGBAReadSwizzle(rgbaReadSwizzle) {}
GrColorType fColorType;
enum {
kUploadData_Flag = 0x1,
// Does Ganesh itself support rendering to this colorType & format pair. Renderability
// still additionally depends on if the format can be an FBO color attachment.
kRenderable_Flag = 0x2,
};
uint32_t fFlags = 0;
uint32_t fFlags;
struct ExternalIOFormats {
GrColorType fColorType = GrColorType::kUnknown;
/** The external format and type are to be used when uploading/downloading data using
data of fColorType and uploading to a texture of a given GrGLFormat and its
intended GrColorType. The fExternalTexImageFormat is the format to use for TexImage
calls. The fExternalReadFormat is used when calling ReadPixels. If either is zero
that signals that either TexImage or ReadPixels is not supported for the combination
of format and color types. */
GrGLenum fExternalType = 0;
GrGLenum fExternalTexImageFormat = 0;
GrGLenum fExternalReadFormat = 0;
// This is the swizzle to apply to the data after it is read back using the
// fExternalReadFormat so that the data is in the form expected by fColorType.
GrSwizzle fReadSwizzle = GrSwizzle::RGBA();
};
GrGLenum externalFormat(GrColorType externalColorType, ExternalFormatUsage usage) const {
for (int i = 0; i < fExternalIOFormatCount; ++i) {
if (fExternalIOFormats[i].fColorType == externalColorType) {
if (usage == kTexImage_ExternalFormatUsage) {
return fExternalIOFormats[i].fExternalTexImageFormat;
} else {
SkASSERT(usage == kReadPixels_ExternalFormatUsage);
return fExternalIOFormats[i].fExternalReadFormat;
}
}
}
return 0;
}
GrGLenum externalType(GrColorType externalColorType) const {
for (int i = 0; i < fExternalIOFormatCount; ++i) {
if (fExternalIOFormats[i].fColorType == externalColorType) {
return fExternalIOFormats[i].fExternalType;
}
}
return 0;
}
std::unique_ptr<ExternalIOFormats[]> fExternalIOFormats;
int fExternalIOFormatCount = 0;
// If data from a surface of this colorType & format is read back to a GrColorType with all
// four color channels this indicates how each channel should be interpreted. May contain
// 0s and 1s.
GrSwizzle fRGBAReadSwizzle = GrSwizzle("rgba");
};
struct FormatInfo {
uint32_t colorTypeFlags(GrColorType colorType) const {
for (int i = 0; i < fColorTypeInfoCount; ++i) {
for (int i = 0; i < fColorTypeInfos.count(); ++i) {
if (fColorTypeInfos[i].fColorType == colorType) {
return fColorTypeInfos[i].fFlags;
}
@ -659,23 +644,13 @@ private:
return 0;
}
GrGLenum externalFormat(GrColorType surfaceColorType, GrColorType externalColorType,
ExternalFormatUsage usage) const {
for (int i = 0; i < fColorTypeInfoCount; ++i) {
if (fColorTypeInfos[i].fColorType == surfaceColorType) {
return fColorTypeInfos[i].externalFormat(externalColorType, usage);
GrSwizzle rgbaReadSwizzle(GrColorType colorType) const {
for (int i = 0; i < fColorTypeInfos.count(); ++i) {
if (fColorTypeInfos[i].fColorType == colorType) {
return fColorTypeInfos[i].fRGBAReadSwizzle;
}
}
return 0;
}
GrGLenum externalType(GrColorType surfaceColorType, GrColorType externalColorType) const {
for (int i = 0; i < fColorTypeInfoCount; ++i) {
if (fColorTypeInfos[i].fColorType == surfaceColorType) {
return fColorTypeInfos[i].externalType(externalColorType);
}
}
return 0;
return GrSwizzle();
}
enum {
@ -729,8 +704,7 @@ private:
// used in the (sole) rendering thread it can cause races if it is glommed into fFlags.
bool fVerifiedColorAttachment = false;
std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos;
int fColorTypeInfoCount = 0;
SkSTArray<1, ColorTypeInfo> fColorTypeInfos;
};
FormatInfo fFormatTable[kGrGLFormatCount];

View File

@ -967,16 +967,14 @@ bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
restoreGLRowLength = true;
}
GrGLFormat textureFormat = glTex->format();
GrColorType textureColorType = GrPixelConfigToColorType(texConfig);
// Internal format comes from the texture desc.
GrGLenum internalFormat;
// External format and type come from the upload data.
GrGLenum externalFormat = 0;
GrGLenum externalType = 0;
this->glCaps().getTexImageFormats(textureFormat, textureColorType, bufferColorType,
&internalFormat, &externalFormat, &externalType);
if (!externalFormat || !externalType) {
GrGLenum externalFormat;
GrGLenum externalType;
auto bufferAsConfig = GrColorTypeToPixelConfig(bufferColorType);
if (!this->glCaps().getTexImageFormats(texConfig, bufferAsConfig, &internalFormat,
&externalFormat, &externalType)) {
return false;
}
@ -1196,17 +1194,13 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
return false;
}
GrGLFormat textureFormat = this->glCaps().pixelConfigToFormat(texConfig);
GrColorType textureColorType = GrPixelConfigToColorType(texConfig);
GrColorType dataColorType = GrPixelConfigToColorType(dataConfig);
// Internal format comes from the texture desc.
GrGLenum internalFormat;
// External format and type come from the upload data.
GrGLenum externalFormat;
GrGLenum externalType;
this->glCaps().getTexImageFormats(textureFormat, textureColorType, dataColorType,
&internalFormat, &externalFormat, &externalType);
if (!externalFormat || !externalType) {
if (!this->glCaps().getTexImageFormats(texConfig, dataConfig, &internalFormat, &externalFormat,
&externalType)) {
return false;
}
// TexStorage requires a sized format, and internalFormat may or may not be
@ -2209,13 +2203,13 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
return false;
}
GrGLFormat surfaceFormat = GrGLBackendFormatToGLFormat(surface->backendFormat());
GrColorType surfaceColorType = GrPixelConfigToColorType(surface->config());
GrGLenum externalFormat = 0;
GrGLenum externalType = 0;
this->glCaps().getReadPixelsFormat(surfaceFormat, surfaceColorType, dstColorType,
&externalFormat, &externalType);
if (!externalFormat || !externalType) {
// TODO: Avoid this conversion by making GrGLCaps work with color types.
auto dstAsConfig = GrColorTypeToPixelConfig(dstColorType);
GrGLenum externalFormat;
GrGLenum externalType;
if (!this->glCaps().getReadPixelsFormat(surface->config(), dstAsConfig, &externalFormat,
&externalType)) {
return false;
}
@ -2250,7 +2244,6 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
SkASSERT(this->glCaps().readPixelsRowBytesSupport());
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowWidthInPixels));
}
auto dstAsConfig = GrColorTypeToPixelConfig(dstColorType);
GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, config_alignment(dstAsConfig)));
bool reattachStencil = false;
@ -3947,8 +3940,8 @@ GrBackendRenderTarget GrGLGpu::createTestingOnlyBackendRenderTarget(int w, int h
GrGLenum externalFormat = 0, externalType = 0;
if (config == kBGRA_8888_GrPixelConfig && this->glCaps().bgraIsInternalFormat()) {
// BGRA render buffers are not supported.
this->glCaps().getTexImageFormats(format, colorType, colorType, &colorBufferFormat,
&externalFormat, &externalType);
this->glCaps().getTexImageFormats(config, config, &colorBufferFormat, &externalFormat,
&externalType);
useTexture = true;
} else {
colorBufferFormat = this->glCaps().getRenderbufferInternalFormat(format);

View File

@ -42,8 +42,6 @@ public:
GrGLenum target() const;
GrGLFormat format() const { return GrGLFormatFromGLEnum(fFormat); }
bool hasBaseLevelBeenBoundToFBO() const { return fBaseLevelHasBeenBoundToFBO; }
void baseLevelWasBoundToFBO() { fBaseLevelHasBeenBoundToFBO = true; }

View File

@ -121,11 +121,6 @@ public:
return SurfaceReadPixelsSupport::kSupported;
}
SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType, const GrBackendFormat&,
GrColorType) const override {
return SupportedRead{GrSwizzle::RGBA(), srcColorType, 1};
}
GrColorType getYUVAColorTypeFromBackendFormat(const GrBackendFormat& format) const override {
if (!format.getMockColorType()) {
return GrColorType::kUnknown;
@ -157,6 +152,10 @@ private:
const SkIRect& srcRect, const SkIPoint& dstPoint) const override {
return true;
}
size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const override {
// arbitrary
return GrSizeAlignUp(GrColorTypeBytesPerPixel(bufferColorType), 4);
}
GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat& format,
GrColorType) const override {

View File

@ -49,8 +49,8 @@ public:
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override {
return SurfaceReadPixelsSupport::kSupported;
}
SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
/**
* Returns both a supported and most prefered stencil format to use in draws.
@ -89,6 +89,10 @@ private:
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const override {
// Transfer buffers not yet supported.
return 0;
}
GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;

View File

@ -871,80 +871,60 @@ GrSwizzle GrMtlCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType
return get_swizzle(format, colorType, true);
}
GrCaps::SupportedRead GrMtlCaps::onSupportedReadPixelsColorType(
GrCaps::SupportedRead GrMtlCaps::supportedReadPixelsColorType(
GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
GrColorType dstColorType) const {
const GrMTLPixelFormat* grMtlFormat = srcBackendFormat.getMtlFormat();
if (!grMtlFormat) {
return {GrSwizzle(), GrColorType::kUnknown, 0};
return {GrSwizzle(), GrColorType::kUnknown};
}
GrColorType readCT = GrColorType::kUnknown;
switch (*grMtlFormat) {
case MTLPixelFormatRGBA8Unorm:
readCT = GrColorType::kRGBA_8888;
break;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888};
case MTLPixelFormatR8Unorm:
if (srcColorType == GrColorType::kAlpha_8) {
readCT = GrColorType::kAlpha_8;
return {GrSwizzle::RGBA(), GrColorType::kAlpha_8};
} else if (srcColorType == GrColorType::kGray_8) {
readCT = GrColorType::kGray_8;
return {GrSwizzle::RGBA(), GrColorType::kGray_8};
}
break;
case MTLPixelFormatBGRA8Unorm:
readCT = GrColorType::kBGRA_8888;
break;
return {GrSwizzle::RGBA(), GrColorType::kBGRA_8888};
#ifdef SK_BIULD_FOR_IOS
case MTLPixelFormatB5G6R5Unorm:
readCT = GrColorType::kBGR_565;
break;
return {GrSwizzle::RGBA(), GrColorType::kBGR_565};
#endif
case MTLPixelFormatRGBA16Float:
if (srcColorType == GrColorType::kRGBA_F16) {
readCT = GrColorType::kRGBA_F16;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16};
} else if (srcColorType == GrColorType::kRGBA_F16_Clamped){
readCT = GrColorType::kRGBA_F16_Clamped;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16_Clamped};
}
break;
case MTLPixelFormatR16Float:
readCT = GrColorType::kAlpha_F16;
break;
return {GrSwizzle::RGBA(), GrColorType::kAlpha_F16};
case MTLPixelFormatRG8Unorm:
readCT = GrColorType::kRG_88;
break;
return {GrSwizzle::RGBA(), GrColorType::kRG_88};
case MTLPixelFormatRGB10A2Unorm:
readCT = GrColorType::kRGBA_1010102;
break;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_1010102};
#ifdef SK_BIULD_FOR_IOS
case MTLPixelFormatABGR4Unorm:
readCT = GrColorType::kABGR_4444;
break;
return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
#endif
case MTLPixelFormatRGBA32Float:
readCT = GrColorType::kRGBA_F32;
break;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F32};
case MTLPixelFormatRGBA8Unorm_sRGB:
readCT = GrColorType::kRGBA_8888_SRGB;
break;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888_SRGB};
case MTLPixelFormatR16Unorm:
readCT = GrColorType::kR_16;
break;
return {GrSwizzle::RGBA(), GrColorType::kR_16};
case MTLPixelFormatRG16Unorm:
readCT = GrColorType::kRG_1616;
break;
return {GrSwizzle::RGBA(), GrColorType::kRG_1616};
// Experimental (for Y416 and mutant P016/P010)
case MTLPixelFormatRGBA16Unorm:
readCT = GrColorType::kRGBA_16161616;
break;
return {GrSwizzle::RGBA(), GrColorType::kRGBA_16161616};
case MTLPixelFormatRG16Float:
readCT = GrColorType::kRG_F16;
break;
return {GrSwizzle::RGBA(), GrColorType::kRG_F16};
default:
// readCT stays as kUnknown
break;
return {GrSwizzle(), GrColorType::kUnknown};
}
// Metal requires the destination offset for copyFromTexture to be a multiple of the textures
// pixels size.
return {GrSwizzle::RGBA(), readCT, static_cast<size_t>(GrColorTypeBytesPerPixel(readCT))};
}

View File

@ -17,6 +17,8 @@ std::unique_ptr<GrOp> GrTransferFromOp::Make(GrRecordingContext* context,
GrColorType dstColorType,
sk_sp<GrGpuBuffer> dstBuffer,
size_t dstOffset) {
SkASSERT(context->priv().caps()->transferFromOffsetAlignment(dstColorType));
SkASSERT(dstOffset % context->priv().caps()->transferFromOffsetAlignment(dstColorType) == 0);
GrOpMemoryPool* pool = context->priv().opMemoryPool();
return pool->allocate<GrTransferFromOp>(srcRect, dstColorType, std::move(dstBuffer), dstOffset);
}

View File

@ -1206,79 +1206,78 @@ GrSwizzle GrVkCaps::getOutputSwizzle(const GrBackendFormat& format, GrColorType
return get_swizzle(format, colorType, true);
}
GrCaps::SupportedRead GrVkCaps::onSupportedReadPixelsColorType(
size_t GrVkCaps::onTransferFromOffsetAlignment(GrColorType bufferColorType) const {
// This GrColorType has 32 bpp but the Vulkan pixel format we use for with may have 24bpp
// (VK_FORMAT_R8G8B8_...) or may be 32 bpp. We don't support post transforming the pixel data
// for transfer-from currently and don't want to have to pass info about the src surface here.
if (bufferColorType == GrColorType::kRGB_888x) {
return false;
}
size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
// The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
switch (bpp & 0b11) {
// bpp is already a multiple of 4.
case 0: return bpp;
// bpp is a multiple of 2 but not 4.
case 2: return 2 * bpp;
// bpp is not a multiple of 2.
default: return 4 * bpp;
}
}
GrCaps::SupportedRead GrVkCaps::supportedReadPixelsColorType(
GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
GrColorType dstColorType) const {
const VkFormat* vkFormat = srcBackendFormat.getVkFormat();
if (!vkFormat) {
return {GrSwizzle(), GrColorType::kUnknown, 0};
}
// The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
size_t offsetAlignment = GrVkBytesPerFormat(*vkFormat);
switch (offsetAlignment & 0b11) {
// bpp is already a multiple of 4.
case 0:
break;
// bpp is a multiple of 2 but not 4.
case 2:
offsetAlignment *= 2;
break;
// bpp is not a multiple of 2.
default:
offsetAlignment *= 4;
break;
return {GrSwizzle(), GrColorType::kUnknown};
}
switch (*vkFormat) {
case VK_FORMAT_R8G8B8A8_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888};
case VK_FORMAT_R8_UNORM:
if (srcColorType == GrColorType::kAlpha_8) {
return {GrSwizzle::RGBA(), GrColorType::kAlpha_8, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kAlpha_8};
} else if (srcColorType == GrColorType::kGray_8) {
return {GrSwizzle::RGBA(), GrColorType::kGray_8, offsetAlignment};
} else {
return {GrSwizzle(), GrColorType::kUnknown, 0};
return {GrSwizzle::RGBA(), GrColorType::kGray_8};
}
case VK_FORMAT_B8G8R8A8_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kBGRA_8888, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kBGRA_8888};
case VK_FORMAT_R5G6B5_UNORM_PACK16:
return {GrSwizzle::RGBA(), GrColorType::kBGR_565, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kBGR_565};
case VK_FORMAT_R16G16B16A16_SFLOAT:
if (srcColorType == GrColorType::kRGBA_F16) {
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16, offsetAlignment};
} else if (srcColorType == GrColorType::kRGBA_F16_Clamped) {
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16_Clamped, offsetAlignment};
} else {
return {GrSwizzle(), GrColorType::kUnknown, 0};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16};
} else if (srcColorType == GrColorType::kRGBA_F16_Clamped){
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F16_Clamped};
}
case VK_FORMAT_R16_SFLOAT:
return {GrSwizzle::RGBA(), GrColorType::kAlpha_F16, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kAlpha_F16};
case VK_FORMAT_R8G8B8_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kRGB_888x, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGB_888x};
case VK_FORMAT_R8G8_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kRG_88, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRG_88};
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
return {GrSwizzle::RGBA(), GrColorType::kRGBA_1010102, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_1010102};
case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
return {GrSwizzle::RGBA(), GrColorType::kABGR_4444, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
return {GrSwizzle::RGBA(), GrColorType::kABGR_4444, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kABGR_4444};
case VK_FORMAT_R32G32B32A32_SFLOAT:
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F32, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_F32};
case VK_FORMAT_R8G8B8A8_SRGB:
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888_SRGB, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_8888_SRGB};
case VK_FORMAT_R16_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kR_16, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kR_16};
case VK_FORMAT_R16G16_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kRG_1616, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRG_1616};
// Experimental (for Y416 and mutant P016/P010)
case VK_FORMAT_R16G16B16A16_UNORM:
return {GrSwizzle::RGBA(), GrColorType::kRGBA_16161616, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRGBA_16161616};
case VK_FORMAT_R16G16_SFLOAT:
return {GrSwizzle::RGBA(), GrColorType::kRG_F16, offsetAlignment};
return {GrSwizzle::RGBA(), GrColorType::kRG_F16};
default:
return {GrSwizzle(), GrColorType::kUnknown, 0};
return {GrSwizzle(), GrColorType::kUnknown};
}
}

View File

@ -53,8 +53,8 @@ public:
int maxRenderTargetSampleCount(VkFormat format) const;
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
SupportedRead supportedReadPixelsColorType(GrColorType, const GrBackendFormat&,
GrColorType) const override;
bool isVkFormatTexturableLinearly(VkFormat format) const {
return SkToBool(FormatInfo::kTextureable_Flag & this->getFormatInfo(format).fLinearFlags);
@ -201,6 +201,7 @@ private:
bool onSurfaceSupportsWritePixels(const GrSurface*) const override;
bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
const SkIRect& srcRect, const SkIPoint& dstPoint) const override;
size_t onTransferFromOffsetAlignment(GrColorType bufferColorType) const override;
GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override;
bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override;

View File

@ -87,14 +87,9 @@ bool SkImage_GpuBase::getROPixels(SkBitmap* dst, CachingHint chint) const {
}
}
sk_sp<GrTextureProxy> texProxy = this->asTextureProxyRef(direct);
GrColorType grColorType = SkColorTypeAndFormatToGrColorType(fContext->priv().caps(),
this->colorType(),
texProxy->backendFormat());
sk_sp<GrSurfaceContext> sContext =
direct->priv().makeWrappedSurfaceContext(std::move(texProxy),
grColorType,
direct->priv().makeWrappedSurfaceContext(this->asTextureProxyRef(direct),
SkColorTypeToGrColorType(this->colorType()),
this->alphaType(),
this->refColorSpace());
if (!sContext) {
@ -145,13 +140,9 @@ bool SkImage_GpuBase::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels,
return false;
}
sk_sp<GrTextureProxy> texProxy = this->asTextureProxyRef(direct);
GrColorType grColorType = SkColorTypeAndFormatToGrColorType(fContext->priv().caps(),
this->colorType(),
texProxy->backendFormat());
sk_sp<GrSurfaceContext> sContext = direct->priv().makeWrappedSurfaceContext(
std::move(texProxy), grColorType, this->alphaType(), this->refColorSpace());
this->asTextureProxyRef(direct), SkColorTypeToGrColorType(this->colorType()),
this->alphaType(), this->refColorSpace());
if (!sContext) {
return false;
}

View File

@ -248,7 +248,7 @@ void basic_transfer_from_test(skiatest::Reporter* reporter, const sk_gpu_test::C
size_t bpp = GrColorTypeBytesPerPixel(allowedRead.fColorType);
size_t fullBufferRowBytes = kTextureWidth * bpp;
size_t partialBufferRowBytes = kPartialWidth * bpp;
size_t offsetAlignment = allowedRead.fOffsetAlignmentForTransferBuffer;
size_t offsetAlignment = caps->transferFromOffsetAlignment(allowedRead.fColorType);
SkASSERT(offsetAlignment);
size_t bufferSize = fullBufferRowBytes * kTextureHeight;