Prepare sRGB encoding conversion for the removal of GrPixelConfig
Standardizes that GrGpu subclass's onRead/WritePixels never do sRGB<->linear conversion. This means that they can eventually take a color type rather than config. It also means direct callers of GrGpu::read/writePixels can never expect conversion (which in practice is no change). Consolidate logic about whether to do sRGB<->linear encoding conversions in GrContext::read/writeSurfacePixels helpers. No change in when conversions are done (yet). This prepares this logic to operate on SkColorSpace and color type rather than config WRT the CPU data. Bug: skia:6718 Change-Id: I346d669624861578f1bb9ea465a7ab4b549117fa Reviewed-on: https://skia-review.googlesource.com/105286 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
95edb43251
commit
9b009bb069
@ -791,13 +791,27 @@ static inline bool GrPixelConfigIs8888Unorm(GrPixelConfig config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the color (non-alpha) components represent sRGB values. It does NOT indicate that
|
||||
// all three color components are present in the config or anything about their order.
|
||||
static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
|
||||
/**
|
||||
* Refers to the encoding of a GPU buffer as it will be interpreted by the GPU when sampling and
|
||||
* blending.
|
||||
*/
|
||||
enum class GrSRGBEncoded : bool { kNo = false, kYes = true };
|
||||
|
||||
/**
|
||||
* Describes whether pixel data encoding should be converted to/from linear/sRGB encoding.
|
||||
*/
|
||||
enum class GrSRGBConversion {
|
||||
kNone,
|
||||
kSRGBToLinear,
|
||||
kLinearToSRGB,
|
||||
};
|
||||
|
||||
// Returns whether the config's color channels are sRGB encoded.
|
||||
static inline GrSRGBEncoded GrPixelConfigIsSRGBEncoded(GrPixelConfig config) {
|
||||
switch (config) {
|
||||
case kSRGBA_8888_GrPixelConfig:
|
||||
case kSBGRA_8888_GrPixelConfig:
|
||||
return true;
|
||||
return GrSRGBEncoded::kYes;
|
||||
case kUnknown_GrPixelConfig:
|
||||
case kAlpha_8_GrPixelConfig:
|
||||
case kAlpha_8_as_Alpha_GrPixelConfig:
|
||||
@ -814,12 +828,15 @@ static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
|
||||
case kAlpha_half_GrPixelConfig:
|
||||
case kAlpha_half_as_Red_GrPixelConfig:
|
||||
case kRGBA_half_GrPixelConfig:
|
||||
return false;
|
||||
return GrSRGBEncoded::kNo;
|
||||
}
|
||||
SK_ABORT("Invalid pixel config");
|
||||
return false;
|
||||
return GrSRGBEncoded::kNo;
|
||||
}
|
||||
|
||||
static inline bool GrPixelConfigIsSRGB(GrPixelConfig config) {
|
||||
return GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(config);
|
||||
}
|
||||
// Takes a config and returns the equivalent config with the R and B order
|
||||
// swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
|
||||
static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
|
||||
|
@ -542,6 +542,63 @@ static bool pm_upm_must_round_trip(GrPixelConfig config, SkColorSpace* colorSpac
|
||||
(kRGBA_8888_GrPixelConfig == config || kBGRA_8888_GrPixelConfig == config);
|
||||
}
|
||||
|
||||
static GrSRGBConversion determine_write_pixels_srgb_conversion(
|
||||
GrPixelConfig srcConfig,
|
||||
const SkColorSpace* srcColorSpace,
|
||||
GrSRGBEncoded dstSRGBEncoded,
|
||||
const SkColorSpace* dstColorSpace) {
|
||||
// No support for sRGB-encoded alpha.
|
||||
if (GrPixelConfigIsAlphaOnly(srcConfig)) {
|
||||
return GrSRGBConversion::kNone;
|
||||
}
|
||||
// When the destination has no color space or it has a ~sRGB gamma but isn't sRGB encoded
|
||||
// (because of caps) then we act in "legacy" mode where no conversions are performed.
|
||||
if (!dstColorSpace ||
|
||||
(dstColorSpace->gammaCloseToSRGB() && GrSRGBEncoded::kNo == dstSRGBEncoded)) {
|
||||
return GrSRGBConversion::kNone;
|
||||
}
|
||||
// Similarly, if the src was sRGB gamma and 8888 but we didn't choose a sRGB config we must be
|
||||
// in legacy mode. For now, anyway.
|
||||
if (srcColorSpace && srcColorSpace->gammaCloseToSRGB() &&
|
||||
GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcConfig) &&
|
||||
GrPixelConfigIs8888Unorm(srcConfig)) {
|
||||
return GrSRGBConversion::kNone;
|
||||
}
|
||||
|
||||
bool srcColorSpaceIsSRGB = srcColorSpace && srcColorSpace->gammaCloseToSRGB();
|
||||
bool dstColorSpaceIsSRGB = dstColorSpace->gammaCloseToSRGB();
|
||||
|
||||
// For now we are assuming that if color space of the dst does not have sRGB gamma then the
|
||||
// texture format is not sRGB encoded and vice versa. Note that we already checked for "legacy"
|
||||
// mode being forced on by caps above. This may change in the future.
|
||||
SkASSERT(dstColorSpaceIsSRGB == (GrSRGBEncoded::kYes == dstSRGBEncoded));
|
||||
|
||||
// Similarly we are assuming that if the color space of the src does not have sRGB gamma then
|
||||
// the CPU pixels don't have a sRGB pixel config. This will become moot soon as we will not
|
||||
// be using GrPixelConfig to describe CPU pixel allocations.
|
||||
SkASSERT(srcColorSpaceIsSRGB == GrPixelConfigIsSRGB(srcConfig));
|
||||
|
||||
if (srcColorSpaceIsSRGB == dstColorSpaceIsSRGB) {
|
||||
return GrSRGBConversion::kNone;
|
||||
}
|
||||
return srcColorSpaceIsSRGB ? GrSRGBConversion::kSRGBToLinear : GrSRGBConversion::kLinearToSRGB;
|
||||
}
|
||||
|
||||
static GrSRGBConversion determine_read_pixels_srgb_conversion(
|
||||
GrSRGBEncoded srcSRGBEncoded,
|
||||
const SkColorSpace* srcColorSpace,
|
||||
GrPixelConfig dstConfig,
|
||||
const SkColorSpace* dstColorSpace) {
|
||||
// This is symmetrical with the write version.
|
||||
switch (determine_write_pixels_srgb_conversion(dstConfig, dstColorSpace, srcSRGBEncoded,
|
||||
srcColorSpace)) {
|
||||
case GrSRGBConversion::kNone: return GrSRGBConversion::kNone;
|
||||
case GrSRGBConversion::kLinearToSRGB: return GrSRGBConversion::kSRGBToLinear;
|
||||
case GrSRGBConversion::kSRGBToLinear: return GrSRGBConversion::kLinearToSRGB;
|
||||
}
|
||||
return GrSRGBConversion::kNone;
|
||||
}
|
||||
|
||||
bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig srcConfig, SkColorSpace* srcColorSpace,
|
||||
@ -590,8 +647,12 @@ bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst,
|
||||
GrGpu::DrawPreference drawPreference = premulOnGpu ? GrGpu::kCallerPrefersDraw_DrawPreference
|
||||
: GrGpu::kNoDraw_DrawPreference;
|
||||
GrGpu::WritePixelTempDrawInfo tempDrawInfo;
|
||||
GrSRGBConversion srgbConversion = determine_write_pixels_srgb_conversion(
|
||||
srcConfig, srcColorSpace, GrPixelConfigIsSRGBEncoded(dstProxy->config()),
|
||||
dst->colorSpaceInfo().colorSpace());
|
||||
if (!fContext->fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height,
|
||||
srcConfig, &drawPreference, &tempDrawInfo)) {
|
||||
srcConfig, srgbConversion, &drawPreference,
|
||||
&tempDrawInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -723,8 +784,12 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src,
|
||||
GrGpu::DrawPreference drawPreference = unpremulOnGpu ? GrGpu::kCallerPrefersDraw_DrawPreference
|
||||
: GrGpu::kNoDraw_DrawPreference;
|
||||
GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
|
||||
GrSRGBConversion srgbConversion = determine_read_pixels_srgb_conversion(
|
||||
GrPixelConfigIsSRGBEncoded(srcProxy->config()), src->colorSpaceInfo().colorSpace(),
|
||||
dstConfig, dstColorSpace);
|
||||
if (!fContext->fGpu->getReadPixelsInfo(srcSurface, srcProxy->origin(), width, height, rowBytes,
|
||||
dstConfig, &drawPreference, &tempDrawInfo)) {
|
||||
dstConfig, srgbConversion, &drawPreference,
|
||||
&tempDrawInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -193,35 +193,65 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||
return this->onCopySurface(dst, dstOrigin, src, srcOrigin, srcRect, dstPoint);
|
||||
}
|
||||
|
||||
bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int width, int height, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference* drawPreference,
|
||||
bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
|
||||
int height, size_t rowBytes, GrPixelConfig dstConfig,
|
||||
GrSRGBConversion srgbConversion, DrawPreference* drawPreference,
|
||||
ReadPixelTempDrawInfo* tempDrawInfo) {
|
||||
SkASSERT(drawPreference);
|
||||
SkASSERT(tempDrawInfo);
|
||||
SkASSERT(srcSurface);
|
||||
SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
|
||||
|
||||
// Default values for intermediate draws. The intermediate texture config matches the src's
|
||||
// Default values for intermediate draws. The intermediate texture config matches the dst's
|
||||
// config, is approx sized to the read rect, no swizzling or spoofing of the dst config.
|
||||
tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
tempDrawInfo->fTempSurfaceDesc.fWidth = width;
|
||||
tempDrawInfo->fTempSurfaceDesc.fHeight = height;
|
||||
tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
|
||||
tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = srcSurface->config();
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
|
||||
tempDrawInfo->fTempSurfaceFit = SkBackingFit::kApprox;
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
|
||||
tempDrawInfo->fReadConfig = readConfig;
|
||||
tempDrawInfo->fReadConfig = dstConfig;
|
||||
|
||||
// We currently do not support reading into the packed formats 565 or 4444 as they are not
|
||||
// required to have read back support on all devices and backends.
|
||||
if (kRGB_565_GrPixelConfig == readConfig || kRGBA_4444_GrPixelConfig == readConfig) {
|
||||
if (kRGB_565_GrPixelConfig == dstConfig || kRGBA_4444_GrPixelConfig == dstConfig) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->onGetReadPixelsInfo(srcSurface, srcOrigin, width, height, rowBytes, readConfig,
|
||||
drawPreference, tempDrawInfo)) {
|
||||
// GrGpu::readPixels doesn't do any sRGB conversions, so we must draw if there is one.
|
||||
switch (srgbConversion) {
|
||||
case GrSRGBConversion::kNone:
|
||||
break;
|
||||
case GrSRGBConversion::kLinearToSRGB:
|
||||
SkASSERT(this->caps()->srgbSupport());
|
||||
// This check goes away when we start referring to CPU data using color type.
|
||||
SkASSERT(GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstConfig));
|
||||
// Currently we don't expect to make a SRGB encoded surface and then read data from it
|
||||
// such that we treat it as though it were linear and is then converted to sRGB.
|
||||
if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(srcSurface->config())) {
|
||||
return false;
|
||||
}
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
break;
|
||||
case GrSRGBConversion::kSRGBToLinear:
|
||||
SkASSERT(this->caps()->srgbSupport());
|
||||
// This assert goes away when we start referring to CPU data using color type.
|
||||
SkASSERT(GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(dstConfig));
|
||||
// We don't currently support reading sRGB encoded data into linear from a surface
|
||||
// unless it is an sRGB-encoded config. That is likely to change when we need to store
|
||||
// sRGB encoded data in 101010102 and F16 textures. We'll have to provoke the caller to
|
||||
// do the conversion in a shader.
|
||||
if (GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcSurface->config())) {
|
||||
return false;
|
||||
}
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this->onGetReadPixelsInfo(srcSurface, srcOrigin, width, height, rowBytes, dstConfig,
|
||||
drawPreference, tempDrawInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -237,9 +267,9 @@ bool GrGpu::getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
|
||||
return true;
|
||||
}
|
||||
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference* drawPreference,
|
||||
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
|
||||
int height, GrPixelConfig srcConfig, GrSRGBConversion srgbConversion,
|
||||
DrawPreference* drawPreference,
|
||||
WritePixelTempDrawInfo* tempDrawInfo) {
|
||||
SkASSERT(drawPreference);
|
||||
SkASSERT(tempDrawInfo);
|
||||
@ -257,6 +287,36 @@ bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
|
||||
tempDrawInfo->fWriteConfig = srcConfig;
|
||||
|
||||
// GrGpu::writePixels doesn't do any sRGB conversions, so we must draw if there is one.
|
||||
switch (srgbConversion) {
|
||||
case GrSRGBConversion::kNone:
|
||||
break;
|
||||
case GrSRGBConversion::kLinearToSRGB:
|
||||
SkASSERT(this->caps()->srgbSupport());
|
||||
// This assert goes away when we start referring to CPU data using color type.
|
||||
SkASSERT(GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(srcConfig));
|
||||
// We don't currently support storing sRGB encoded data in a surface unless it is
|
||||
// an SRGB-encoded config. That is likely to change when we need to store sRGB encoded
|
||||
// data in 101010102 and F16 textures. We'll have to provoke the caller to do the
|
||||
// conversion in a shader.
|
||||
if (GrSRGBEncoded::kNo == GrPixelConfigIsSRGBEncoded(dstSurface->config())) {
|
||||
return false;
|
||||
}
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
break;
|
||||
case GrSRGBConversion::kSRGBToLinear:
|
||||
SkASSERT(this->caps()->srgbSupport());
|
||||
// This assert goes away when we start referring to CPU data using color type.
|
||||
SkASSERT(GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(srcConfig));
|
||||
// Currently we don't expect to make a SRGB encoded surface and then succeed at
|
||||
// treating it as though it were linear and then convert to sRGB.
|
||||
if (GrSRGBEncoded::kYes == GrPixelConfigIsSRGBEncoded(dstSurface->config())) {
|
||||
return false;
|
||||
}
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this->onGetWritePixelsInfo(dstSurface, dstOrigin, width, height, srcConfig, drawPreference,
|
||||
tempDrawInfo)) {
|
||||
return false;
|
||||
|
@ -199,9 +199,9 @@ public:
|
||||
* that would allow a successful readPixels call. The passed width, height, and rowBytes,
|
||||
* must be non-zero and already reflect clipping to the src bounds.
|
||||
*/
|
||||
bool getReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int readWidth, int readHeight, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference*, ReadPixelTempDrawInfo*);
|
||||
bool getReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width,
|
||||
int height, size_t rowBytes, GrPixelConfig,
|
||||
GrSRGBConversion, DrawPreference*, ReadPixelTempDrawInfo*);
|
||||
|
||||
/** Info struct returned by getWritePixelsInfo about performing an intermediate draw in order
|
||||
to write pixels to a GrSurface for either performance or correctness reasons. */
|
||||
@ -226,18 +226,19 @@ public:
|
||||
* that would allow a successful transfer of the src pixels to the dst. The passed width,
|
||||
* height, and rowBytes, must be non-zero and already reflect clipping to the dst bounds.
|
||||
*/
|
||||
bool getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference*, WritePixelTempDrawInfo*);
|
||||
bool getWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
|
||||
GrPixelConfig, GrSRGBConversion, DrawPreference*,
|
||||
WritePixelTempDrawInfo*);
|
||||
|
||||
/**
|
||||
* Reads a rectangle of pixels from a render target.
|
||||
* Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
|
||||
*
|
||||
* @param surface The surface to read from
|
||||
* @param left left edge of the rectangle to read (inclusive)
|
||||
* @param top top edge of the rectangle to read (inclusive)
|
||||
* @param width width of rectangle to read in pixels.
|
||||
* @param height height of rectangle to read in pixels.
|
||||
* @param config the pixel config of the destination buffer
|
||||
* @param dstConfig the pixel config of the destination buffer
|
||||
* @param buffer memory to read the rectangle into.
|
||||
* @param rowBytes the number of bytes between consecutive rows. Zero
|
||||
* means rows are tightly packed.
|
||||
@ -248,39 +249,32 @@ public:
|
||||
* because of a unsupported pixel config or because no render
|
||||
* target is currently set.
|
||||
*/
|
||||
bool readPixels(GrSurface* surface, GrSurfaceOrigin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config, void* buffer, size_t rowBytes);
|
||||
bool readPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
|
||||
GrPixelConfig dstConfig, void* buffer, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Updates the pixels in a rectangle of a surface.
|
||||
* Updates the pixels in a rectangle of a surface. No sRGB/linear conversions are performed.
|
||||
*
|
||||
* @param surface The surface to write to.
|
||||
* @param left left edge of the rectangle to write (inclusive)
|
||||
* @param top top edge of the rectangle to write (inclusive)
|
||||
* @param width width of rectangle to write in pixels.
|
||||
* @param height height of rectangle to write in pixels.
|
||||
* @param config the pixel config of the source buffer
|
||||
* @param srcConfig the pixel config of the source buffer
|
||||
* @param texels array of mipmap levels containing texture data
|
||||
* @param mipLevelCount number of levels in 'texels'
|
||||
*/
|
||||
bool writePixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config,
|
||||
GrPixelConfig srcConfig,
|
||||
const GrMipLevel texels[], int mipLevelCount);
|
||||
|
||||
/**
|
||||
* This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
|
||||
* It then calls writePixels with that SkTArray.
|
||||
*
|
||||
* @param buffer memory to read pixels from.
|
||||
* @param rowBytes number of bytes between consecutive rows. Zero
|
||||
* means rows are tightly packed.
|
||||
*/
|
||||
bool writePixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config, const void* buffer,
|
||||
size_t rowBytes);
|
||||
bool writePixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width,
|
||||
int height, GrPixelConfig, const void* buffer, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Updates the pixels in a rectangle of a texture using a buffer
|
||||
@ -293,16 +287,15 @@ public:
|
||||
* @param top top edge of the rectangle to write (inclusive)
|
||||
* @param width width of rectangle to write in pixels.
|
||||
* @param height height of rectangle to write in pixels.
|
||||
* @param config the pixel config of the source buffer
|
||||
* @param bufferConfig the pixel config of the source buffer
|
||||
* @param transferBuffer GrBuffer to read pixels from (type must be "kXferCpuToGpu")
|
||||
* @param offset offset from the start of the buffer
|
||||
* @param rowBytes number of bytes between consecutive rows in the buffer. Zero
|
||||
* means rows are tightly packed.
|
||||
*/
|
||||
bool transferPixels(GrTexture* texture,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config, GrBuffer* transferBuffer,
|
||||
size_t offset, size_t rowBytes);
|
||||
bool transferPixels(GrTexture* texture, int left, int top, int width, int height,
|
||||
GrPixelConfig bufferConfig, GrBuffer* transferBuffer, size_t offset,
|
||||
size_t rowBytes);
|
||||
|
||||
// After the client interacts directly with the 3D context state the GrGpu
|
||||
// must resync its internal state and assumptions about 3D context state.
|
||||
@ -567,14 +560,11 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int readWidth, int readHeight,
|
||||
size_t rowBytes, GrPixelConfig readConfig, DrawPreference*,
|
||||
virtual bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
|
||||
size_t rowBytes, GrPixelConfig, DrawPreference*,
|
||||
ReadPixelTempDrawInfo*) = 0;
|
||||
virtual bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference*,
|
||||
WritePixelTempDrawInfo*) = 0;
|
||||
virtual bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
|
||||
GrPixelConfig, DrawPreference*, WritePixelTempDrawInfo*) = 0;
|
||||
|
||||
// overridden by backend-specific derived class to perform the surface read
|
||||
virtual bool onReadPixels(GrSurface*, GrSurfaceOrigin,
|
||||
|
@ -81,12 +81,13 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) {
|
||||
GrDeferredTextureUploadWritePixelsFn wp = [this](GrTextureProxy* dstProxy, int left, int top,
|
||||
int width, int height, GrPixelConfig srcConfig,
|
||||
const void* buffer, size_t rowBytes) {
|
||||
// We don't allow srgb conversions via op flush state uploads.
|
||||
static constexpr auto kSRGBConversion = GrSRGBConversion::kNone;
|
||||
GrSurface* dstSurface = dstProxy->priv().peekSurface();
|
||||
GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
|
||||
GrGpu::WritePixelTempDrawInfo tempInfo;
|
||||
if (!fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(),
|
||||
width, height, srcConfig,
|
||||
&drawPreference, &tempInfo)) {
|
||||
if (!fGpu->getWritePixelsInfo(dstSurface, dstProxy->origin(), width, height, srcConfig,
|
||||
kSRGBConversion, &drawPreference, &tempInfo)) {
|
||||
return false;
|
||||
}
|
||||
if (GrGpu::kNoDraw_DrawPreference == drawPreference) {
|
||||
|
@ -665,6 +665,14 @@ bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri
|
||||
GrPixelConfig srcConfig,
|
||||
DrawPreference* drawPreference,
|
||||
WritePixelTempDrawInfo* tempDrawInfo) {
|
||||
if (*drawPreference != kNoDraw_DrawPreference) {
|
||||
// We assume the base class has only inserted a draw for sRGB reasons. So the temp surface
|
||||
// has the config of the original src data. There is no swizzling nor src config spoofing.
|
||||
SkASSERT(tempDrawInfo->fWriteConfig == srcConfig);
|
||||
SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
|
||||
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
|
||||
}
|
||||
|
||||
if (SkToBool(dstSurface->asRenderTarget())) {
|
||||
if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) {
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
@ -694,10 +702,6 @@ bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
}
|
||||
|
||||
if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConfig)) {
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
}
|
||||
|
||||
bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcConfig) == dstSurface->config();
|
||||
|
||||
if (configsAreRBSwaps) {
|
||||
@ -731,16 +735,11 @@ bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri
|
||||
}
|
||||
|
||||
static bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surface,
|
||||
GrPixelConfig config) {
|
||||
GrPixelConfig config) {
|
||||
if (!glTex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
|
||||
if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write or transfer of pixels is not implemented for TEXTURE_EXTERNAL textures
|
||||
if (GR_GL_TEXTURE_EXTERNAL == glTex->target()) {
|
||||
return false;
|
||||
@ -749,23 +748,21 @@ static bool check_write_and_transfer_input(GrGLTexture* glTex, GrSurface* surfac
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config,
|
||||
const GrMipLevel texels[],
|
||||
int mipLevelCount) {
|
||||
bool GrGLGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top,
|
||||
int width, int height, GrPixelConfig dstConfig,
|
||||
const GrMipLevel texels[], int mipLevelCount) {
|
||||
GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
|
||||
|
||||
if (!check_write_and_transfer_input(glTex, surface, config)) {
|
||||
if (!check_write_and_transfer_input(glTex, surface, dstConfig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->setScratchTextureUnit();
|
||||
GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
|
||||
|
||||
return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(),
|
||||
origin, glTex->target(), kWrite_UploadType,
|
||||
left, top, width, height, config, texels, mipLevelCount);
|
||||
return this->uploadTexData(glTex->config(), glTex->width(), glTex->height(), origin,
|
||||
glTex->target(), kWrite_UploadType, left, top, width, height,
|
||||
dstConfig, texels, mipLevelCount);
|
||||
}
|
||||
|
||||
// For GL_[UN]PACK_ALIGNMENT.
|
||||
@ -798,10 +795,9 @@ static inline GrGLint config_alignment(GrPixelConfig config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool GrGLGpu::onTransferPixels(GrTexture* texture,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config, GrBuffer* transferBuffer,
|
||||
size_t offset, size_t rowBytes) {
|
||||
bool GrGLGpu::onTransferPixels(GrTexture* texture, int left, int top, int width, int height,
|
||||
GrPixelConfig config, GrBuffer* transferBuffer, size_t offset,
|
||||
size_t rowBytes) {
|
||||
GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
|
||||
GrPixelConfig texConfig = glTex->config();
|
||||
SkASSERT(this->caps()->isConfigTexturable(texConfig));
|
||||
@ -2163,44 +2159,31 @@ bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig rea
|
||||
}
|
||||
}
|
||||
|
||||
static bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) {
|
||||
if (GrPixelConfigIsSRGB(a)) {
|
||||
return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b);
|
||||
} else if (GrPixelConfigIsSRGB(b)) {
|
||||
return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int width, int height, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference* drawPreference,
|
||||
bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
|
||||
int height, size_t rowBytes, GrPixelConfig dstConfig,
|
||||
DrawPreference* drawPreference,
|
||||
ReadPixelTempDrawInfo* tempDrawInfo) {
|
||||
if (*drawPreference != kNoDraw_DrawPreference) {
|
||||
// We assume the base class has only inserted a draw for sRGB reasons. So the
|
||||
// the temp surface has the config of the dst data. There is no swizzling, nor dst config
|
||||
// spoofing.
|
||||
SkASSERT(tempDrawInfo->fReadConfig == dstConfig);
|
||||
SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == dstConfig);
|
||||
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
|
||||
}
|
||||
GrPixelConfig srcConfig = srcSurface->config();
|
||||
|
||||
tempDrawInfo->fTempSurfaceFit = this->glCaps().partialFBOReadIsSlow() ? SkBackingFit::kExact
|
||||
: SkBackingFit::kApprox;
|
||||
|
||||
if (requires_srgb_conversion(srcConfig, readConfig)) {
|
||||
if (!this->readPixelsSupported(readConfig, readConfig)) {
|
||||
return false;
|
||||
}
|
||||
// Draw to do srgb to linear conversion or vice versa.
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
|
||||
tempDrawInfo->fReadConfig = readConfig;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig &&
|
||||
if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == dstConfig &&
|
||||
this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelConfig)) {
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
|
||||
tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig;
|
||||
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
|
||||
} else if (this->glCaps().rgbaToBgraReadbackConversionsAreSlow() &&
|
||||
GrBytesPerPixel(readConfig) == 4 &&
|
||||
GrPixelConfigSwapRAndB(readConfig) == srcConfig &&
|
||||
GrBytesPerPixel(dstConfig) == 4 && GrPixelConfigSwapRAndB(dstConfig) == srcConfig &&
|
||||
this->readPixelsSupported(srcSurface, srcConfig)) {
|
||||
// Mesa 3D takes a slow path on when reading back BGRA from an RGBA surface and vice-versa.
|
||||
// Better to do a draw with a R/B swap and then read as the original config.
|
||||
@ -2208,8 +2191,8 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrig
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
|
||||
tempDrawInfo->fReadConfig = srcConfig;
|
||||
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
|
||||
} else if (!this->readPixelsSupported(srcSurface, readConfig)) {
|
||||
if (readConfig == kBGRA_8888_GrPixelConfig &&
|
||||
} else if (!this->readPixelsSupported(srcSurface, dstConfig)) {
|
||||
if (dstConfig == kBGRA_8888_GrPixelConfig &&
|
||||
this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig) &&
|
||||
this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) {
|
||||
// We're trying to read BGRA but it's not supported. If RGBA is renderable and
|
||||
@ -2219,9 +2202,10 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrig
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
|
||||
tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
} else if (readConfig == kSBGRA_8888_GrPixelConfig &&
|
||||
this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
|
||||
this->readPixelsSupported(kSRGBA_8888_GrPixelConfig, kSRGBA_8888_GrPixelConfig)) {
|
||||
} else if (dstConfig == kSBGRA_8888_GrPixelConfig &&
|
||||
this->glCaps().canConfigBeFBOColorAttachment(kSRGBA_8888_GrPixelConfig) &&
|
||||
this->readPixelsSupported(kSRGBA_8888_GrPixelConfig,
|
||||
kSRGBA_8888_GrPixelConfig)) {
|
||||
// We're trying to read sBGRA but it's not supported. If sRGBA is renderable and
|
||||
// we can read it back, then do a swizzling draw to a sRGBA and read it back (which
|
||||
// will effectively be sBGRA).
|
||||
@ -2229,45 +2213,40 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrig
|
||||
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
|
||||
tempDrawInfo->fReadConfig = kSRGBA_8888_GrPixelConfig;
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
} else if (readConfig == kAlpha_8_GrPixelConfig) {
|
||||
// onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
|
||||
} else if (dstConfig == kAlpha_8_GrPixelConfig) {
|
||||
// onReadPixels implements a fallback for cases where we want to read kAlpha_8,
|
||||
// it's unsupported, but 32bit RGBA reads are supported.
|
||||
// Don't attempt to do any srgb conversions since we only care about alpha.
|
||||
GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig;
|
||||
if (GrPixelConfigIsSRGB(srcSurface->config())) {
|
||||
cpuTempConfig = kSRGBA_8888_GrPixelConfig;
|
||||
}
|
||||
if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) {
|
||||
if (!this->readPixelsSupported(srcSurface, kRGBA_8888_GrPixelConfig)) {
|
||||
// If we can't read RGBA from the src try to draw to a kRGBA_8888 (or kSRGBA_8888)
|
||||
// first and then onReadPixels will read that to a 32bit temporary buffer.
|
||||
if (this->glCaps().canConfigBeFBOColorAttachment(cpuTempConfig)) {
|
||||
if (this->glCaps().canConfigBeFBOColorAttachment(kRGBA_8888_GrPixelConfig)) {
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig;
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
|
||||
tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
|
||||
SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig);
|
||||
}
|
||||
} else if (readConfig == kRGBA_half_GrPixelConfig &&
|
||||
} else if (dstConfig == kRGBA_half_GrPixelConfig &&
|
||||
this->readPixelsSupported(srcSurface, kRGBA_float_GrPixelConfig)) {
|
||||
// If reading in half float format is not supported, then read in float format.
|
||||
return true;
|
||||
} else if (this->glCaps().canConfigBeFBOColorAttachment(readConfig) &&
|
||||
this->readPixelsSupported(readConfig, readConfig)) {
|
||||
} else if (this->glCaps().canConfigBeFBOColorAttachment(dstConfig) &&
|
||||
this->readPixelsSupported(dstConfig, dstConfig)) {
|
||||
// Do a draw to convert from the src config to the read config.
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
|
||||
tempDrawInfo->fReadConfig = readConfig;
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
|
||||
tempDrawInfo->fReadConfig = dstConfig;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((srcSurface->asRenderTarget() || this->glCaps().canConfigBeFBOColorAttachment(srcConfig)) &&
|
||||
read_pixels_pays_for_y_flip(srcOrigin, this->glCaps(), width, height, readConfig,
|
||||
read_pixels_pays_for_y_flip(srcOrigin, this->glCaps(), width, height, dstConfig,
|
||||
rowBytes)) {
|
||||
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
|
||||
}
|
||||
@ -2288,19 +2267,10 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
return false;
|
||||
}
|
||||
|
||||
// OpenGL doesn't do sRGB <-> linear conversions when reading and writing pixels.
|
||||
if (requires_srgb_conversion(surface->config(), config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We have a special case fallback for reading eight bit alpha. We will read back all four 8
|
||||
// bit channels as RGBA and then extract A.
|
||||
if (!this->readPixelsSupported(surface, config)) {
|
||||
// Don't attempt to do any srgb conversions since we only care about alpha.
|
||||
GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig;
|
||||
if (GrPixelConfigIsSRGB(surface->config())) {
|
||||
tempConfig = kSRGBA_8888_GrPixelConfig;
|
||||
}
|
||||
if (kAlpha_8_GrPixelConfig == config &&
|
||||
this->readPixelsSupported(surface, tempConfig)) {
|
||||
std::unique_ptr<uint32_t[]> temp(new uint32_t[width * height * 4]);
|
||||
|
@ -63,16 +63,6 @@ public:
|
||||
void generateMipmaps(const GrSamplerState& params, bool allowSRGBInputs, GrGLTexture* texture,
|
||||
GrSurfaceOrigin textureOrigin);
|
||||
|
||||
bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int readWidth, int readHeight, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference*,
|
||||
ReadPixelTempDrawInfo*) override;
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference*,
|
||||
WritePixelTempDrawInfo*) override;
|
||||
|
||||
// These functions should be used to bind GL objects. They track the GL state and skip redundant
|
||||
// bindings. Making the equivalent glBind calls directly will confuse the state tracking.
|
||||
void bindVertexArray(GrGLuint id) {
|
||||
@ -240,6 +230,12 @@ private:
|
||||
// variations above, depending on whether the surface is a render target or not.
|
||||
bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
|
||||
|
||||
bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, size_t rowBytes,
|
||||
GrPixelConfig, DrawPreference*, ReadPixelTempDrawInfo*) override;
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrPixelConfig,
|
||||
DrawPreference*, WritePixelTempDrawInfo*) override;
|
||||
|
||||
bool onReadPixels(GrSurface*, GrSurfaceOrigin,
|
||||
int left, int top,
|
||||
int width, int height,
|
||||
|
@ -25,25 +25,6 @@ public:
|
||||
|
||||
~GrMockGpu() override {}
|
||||
|
||||
bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int readWidth, int readHeight, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference*,
|
||||
ReadPixelTempDrawInfo*) override { return true; }
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference*,
|
||||
WritePixelTempDrawInfo*) override { return true; }
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||
GrSurface* src, GrSurfaceOrigin srcOrigin,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) override { return true; }
|
||||
|
||||
void onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const GrStencilSettings&,
|
||||
int* effectiveSampleCnt, SamplePattern*) override {
|
||||
*effectiveSampleCnt = rt->numStencilSamples();
|
||||
}
|
||||
|
||||
GrGpuRTCommandBuffer* createCommandBuffer(
|
||||
GrRenderTarget*, GrSurfaceOrigin,
|
||||
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
|
||||
@ -99,6 +80,18 @@ private:
|
||||
GrBuffer* onCreateBuffer(size_t sizeInBytes, GrBufferType, GrAccessPattern,
|
||||
const void*) override;
|
||||
|
||||
bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
|
||||
size_t rowBytes, GrPixelConfig, DrawPreference*,
|
||||
ReadPixelTempDrawInfo*) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin, int width,
|
||||
int height, GrPixelConfig, DrawPreference*,
|
||||
WritePixelTempDrawInfo*) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onReadPixels(GrSurface* surface, GrSurfaceOrigin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig,
|
||||
@ -121,6 +114,17 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
|
||||
GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const GrStencilSettings&,
|
||||
int* effectiveSampleCnt, SamplePattern*) override {
|
||||
*effectiveSampleCnt = rt->numStencilSamples();
|
||||
}
|
||||
|
||||
void onResolveRenderTarget(GrRenderTarget* target) override { return; }
|
||||
|
||||
void onFinishFlush(bool insertedSemaphores) override {}
|
||||
|
@ -340,6 +340,14 @@ bool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOri
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference* drawPreference,
|
||||
WritePixelTempDrawInfo* tempDrawInfo) {
|
||||
if (*drawPreference != kNoDraw_DrawPreference) {
|
||||
// We assume the base class has only inserted a draw for sRGB reasons. So the temp surface
|
||||
// has the config of the original src data. There is no swizzling nor src config spoofing.
|
||||
SkASSERT(tempDrawInfo->fWriteConfig == srcConfig);
|
||||
SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
|
||||
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
|
||||
}
|
||||
|
||||
GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
|
||||
|
||||
if (dstSurface->config() == srcConfig) {
|
||||
@ -381,11 +389,6 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
return false;
|
||||
}
|
||||
|
||||
// We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
|
||||
if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
bool linearTiling = vkTex->isLinearTiled();
|
||||
if (linearTiling) {
|
||||
@ -435,11 +438,6 @@ bool GrVkGpu::onTransferPixels(GrTexture* texture,
|
||||
return false;
|
||||
}
|
||||
|
||||
// We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
|
||||
if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkDEBUGCODE(
|
||||
SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
|
||||
SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
|
||||
@ -1859,29 +1857,35 @@ void GrVkGpu::onQueryMultisampleSpecs(GrRenderTarget* rt, GrSurfaceOrigin, const
|
||||
*effectiveSampleCnt = rt->numStencilSamples();
|
||||
}
|
||||
|
||||
bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int width, int height, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference* drawPreference,
|
||||
bool GrVkGpu::onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin, int width,
|
||||
int height, size_t rowBytes, GrPixelConfig dstConfig,
|
||||
DrawPreference* drawPreference,
|
||||
ReadPixelTempDrawInfo* tempDrawInfo) {
|
||||
if (srcSurface->config() == readConfig) {
|
||||
if (*drawPreference != kNoDraw_DrawPreference) {
|
||||
// We assume the base class has only inserted a draw for sRGB reasons. So the
|
||||
// the temp surface has the config of the dst data. There is no swizzling nor dst config.
|
||||
// spoofing.
|
||||
SkASSERT(tempDrawInfo->fReadConfig == dstConfig);
|
||||
SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == dstConfig);
|
||||
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
|
||||
}
|
||||
|
||||
if (srcSurface->config() == dstConfig) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any config change requires a draw
|
||||
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
|
||||
tempDrawInfo->fReadConfig = readConfig;
|
||||
tempDrawInfo->fTempSurfaceDesc.fConfig = dstConfig;
|
||||
tempDrawInfo->fReadConfig = dstConfig;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig config,
|
||||
void* buffer,
|
||||
size_t rowBytes) {
|
||||
bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width,
|
||||
int height, GrPixelConfig dstConfig, void* buffer, size_t rowBytes) {
|
||||
VkFormat pixelFormat;
|
||||
if (!GrPixelConfigToVkFormat(config, &pixelFormat)) {
|
||||
if (!GrPixelConfigToVkFormat(dstConfig, &pixelFormat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1916,7 +1920,7 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, GrSurfaceOrigin origin,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
false);
|
||||
|
||||
size_t bpp = GrBytesPerPixel(config);
|
||||
size_t bpp = GrBytesPerPixel(dstConfig);
|
||||
size_t tightRowBytes = bpp * width;
|
||||
bool flipY = kBottomLeft_GrSurfaceOrigin == origin;
|
||||
|
||||
|
@ -64,23 +64,6 @@ public:
|
||||
kSkip_SyncQueue
|
||||
};
|
||||
|
||||
bool onGetReadPixelsInfo(GrSurface* srcSurface, GrSurfaceOrigin srcOrigin,
|
||||
int readWidth, int readHeight, size_t rowBytes,
|
||||
GrPixelConfig readConfig, DrawPreference*,
|
||||
ReadPixelTempDrawInfo*) override;
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin,
|
||||
int width, int height,
|
||||
GrPixelConfig srcConfig, DrawPreference*,
|
||||
WritePixelTempDrawInfo*) override;
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
|
||||
GrSurface* src, GrSurfaceOrigin srcOrigin,
|
||||
const SkIRect& srcRect, const SkIPoint& dstPoint) override;
|
||||
|
||||
void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
|
||||
int* effectiveSampleCnt, SamplePattern*) override;
|
||||
|
||||
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
|
||||
|
||||
GrBackendTexture createTestingOnlyBackendTexture(void* pixels, int w, int h,
|
||||
@ -193,11 +176,14 @@ private:
|
||||
GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern,
|
||||
const void* data) override;
|
||||
|
||||
bool onReadPixels(GrSurface* surface, GrSurfaceOrigin,
|
||||
int left, int top, int width, int height,
|
||||
GrPixelConfig,
|
||||
void* buffer,
|
||||
size_t rowBytes) override;
|
||||
bool onGetReadPixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, size_t rowBytes,
|
||||
GrPixelConfig, DrawPreference*, ReadPixelTempDrawInfo*) override;
|
||||
|
||||
bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrPixelConfig,
|
||||
DrawPreference*, WritePixelTempDrawInfo*) override;
|
||||
|
||||
bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
|
||||
GrPixelConfig, void* buffer, size_t rowBytes) override;
|
||||
|
||||
bool onWritePixels(GrSurface* surface, GrSurfaceOrigin,
|
||||
int left, int top, int width, int height,
|
||||
@ -208,6 +194,13 @@ private:
|
||||
GrPixelConfig config, GrBuffer* transferBuffer,
|
||||
size_t offset, size_t rowBytes) override;
|
||||
|
||||
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin, GrSurface* src,
|
||||
GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
|
||||
const SkIPoint& dstPoint) override;
|
||||
|
||||
void onQueryMultisampleSpecs(GrRenderTarget*, GrSurfaceOrigin, const GrStencilSettings&,
|
||||
int* effectiveSampleCnt, SamplePattern*) override;
|
||||
|
||||
void onFinishFlush(bool insertedSemaphores) override;
|
||||
|
||||
// Ends and submits the current command buffer to the queue and then creates a new command
|
||||
|
Loading…
Reference in New Issue
Block a user