Remove GrGpu::getWritePixelsInfo

Change-Id: I30f9eed774b0b659ee91949a234bcc112fbee035
Reviewed-on: https://skia-review.googlesource.com/131480
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2018-06-01 11:55:08 -04:00 committed by Skia Commit-Bot
parent bc9f3b0f9c
commit 0ba9fa0233
9 changed files with 4 additions and 331 deletions

View File

@ -214,84 +214,6 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
canDiscardOutsideDstRect);
}
bool GrGpu::getWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
int height, GrColorType srcColorType,
GrSRGBConversion srgbConversion, DrawPreference* drawPreference,
WritePixelTempDrawInfo* tempDrawInfo) {
SkASSERT(drawPreference);
SkASSERT(tempDrawInfo);
SkASSERT(dstSurface);
SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
GrPixelConfig tempSurfaceConfig = kUnknown_GrPixelConfig;
// GrGpu::writePixels doesn't do any sRGB conversions, so we must draw if there is one.
switch (srgbConversion) {
case GrSRGBConversion::kNone:
// We support writing just A to a RGBA. In that case there is no sRGB version of the
// src format but we still want to succeed.
if (GrColorTypeIsAlphaOnly(srcColorType)) {
tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo);
} else {
tempSurfaceConfig = GrColorTypeToPixelConfig(
srcColorType, GrPixelConfigIsSRGBEncoded(dstSurface->config()));
}
break;
case GrSRGBConversion::kLinearToSRGB:
SkASSERT(this->caps()->srgbSupport());
// This assert goes away when we start referring to CPU data using color type.
tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kNo);
// 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 (!GrPixelConfigIsSRGB(dstSurface->config())) {
return false;
}
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
break;
case GrSRGBConversion::kSRGBToLinear:
SkASSERT(this->caps()->srgbSupport());
tempSurfaceConfig = GrColorTypeToPixelConfig(srcColorType, GrSRGBEncoded::kYes);
// 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 (kUnknown_GrPixelConfig == tempSurfaceConfig) {
return false;
}
// Default values for intermediate draws. The intermediate texture config matches the dst's
// config, is approx sized to the write rect, no swizzling or sppofing of the src config.
tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
tempDrawInfo->fTempSurfaceDesc.fConfig = tempSurfaceConfig;
tempDrawInfo->fTempSurfaceDesc.fWidth = width;
tempDrawInfo->fTempSurfaceDesc.fHeight = height;
tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 1;
tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
tempDrawInfo->fWriteColorType = srcColorType;
if (!this->onGetWritePixelsInfo(dstSurface, dstOrigin, width, height, srcColorType,
drawPreference, tempDrawInfo)) {
return false;
}
// Check to see if we're going to request that the caller draw when drawing is not possible.
if (!dstSurface->asRenderTarget() ||
!this->caps()->isConfigTexturable(tempDrawInfo->fTempSurfaceDesc.fConfig)) {
// If we don't have a fallback to a straight upload then fail.
if (kRequireDraw_DrawPreference == *drawPreference /*TODO ||
!this->caps()->isConfigTexturable(srcConfig)*/) {
return false;
}
*drawPreference = kNoDraw_DrawPreference;
}
return true;
}
bool GrGpu::readPixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top, int width,
int height, GrColorType dstColorType, void* buffer, size_t rowBytes) {
SkASSERT(surface);

View File

@ -141,69 +141,6 @@ public:
*/
void resolveRenderTarget(GrRenderTarget*);
/** Describes why an intermediate draw must/should be performed before readPixels. */
enum DrawPreference {
/**
* On input means that the caller would proceed without draw if the GrGpu doesn't request
* one. On output means that the GrGpu is not requesting a draw.
*/
kNoDraw_DrawPreference,
/**
* Means that the client would prefer a draw for performance of the readback but
* can satisfy a straight readPixels call on the inputs without an intermediate draw.
* getReadPixelsInfo will never set the draw preference to this value but may leave
* it set.
*/
kCallerPrefersDraw_DrawPreference,
/**
* On output means that GrGpu would prefer a draw for performance of the readback but
* can satisfy a straight readPixels call on the inputs without an intermediate draw. The
* caller of getReadPixelsInfo should never specify this on intput.
*/
kGpuPrefersDraw_DrawPreference,
/**
* On input means that the caller requires a draw to do a transformation and there is no
* CPU fallback. On output means that GrGpu can only satisfy the readPixels request if the
* intermediate draw is performed.
*/
kRequireDraw_DrawPreference
};
/**
* Info struct returned by getWritePixelsInfo about performing an intermediate draw in order
* to write pixels to a GrSurface for either performance or correctness reasons.
*/
struct WritePixelTempDrawInfo {
/**
* If the GrGpu is requesting that the caller upload to an intermediate surface and draw
* that to the dst then this is the descriptor for the intermediate surface. The caller
* should upload the pixels such that the upper left pixel of the upload rect is at 0,0 in
* the intermediate surface
*/
GrSurfaceDesc fTempSurfaceDesc;
/**
* Swizzle to apply during the draw. This is used to compensate for either feature or
* performance limitations in the underlying 3D API.
*/
GrSwizzle fSwizzle;
/**
* The color type that should be specified when uploading the *original* data to the temp
* surface before the draw. This may be different than the original src color type in
* order to compensate for swizzling that will occur when drawing. The original gamma
* encoding is always used.
*/
GrColorType fWriteColorType;
};
/**
* Used to negotiate whether and how an intermediate surface should be used to write pixels to
* a GrSurface. If this returns false then GrGpu could not deduce an intermediate draw
* 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*, GrSurfaceOrigin, int width, int height, GrColorType,
GrSRGBConversion, DrawPreference*, WritePixelTempDrawInfo*);
/**
* Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
*
@ -472,16 +409,6 @@ public:
}
protected:
static void ElevateDrawPreference(GrGpu::DrawPreference* preference,
GrGpu::DrawPreference elevation) {
GR_STATIC_ASSERT(GrGpu::kCallerPrefersDraw_DrawPreference > GrGpu::kNoDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kGpuPrefersDraw_DrawPreference >
GrGpu::kCallerPrefersDraw_DrawPreference);
GR_STATIC_ASSERT(GrGpu::kRequireDraw_DrawPreference >
GrGpu::kGpuPrefersDraw_DrawPreference);
*preference = SkTMax(*preference, elevation);
}
// Handles cases where a surface will be updated without a call to flushRenderTarget.
void didWriteToSurface(GrSurface* surface, GrSurfaceOrigin origin, const SkIRect* bounds,
uint32_t mipLevels = 1) const;
@ -517,9 +444,6 @@ private:
virtual GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
const void* data) = 0;
virtual bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height,
GrColorType, DrawPreference*, WritePixelTempDrawInfo*) = 0;
// overridden by backend-specific derived class to perform the surface read
virtual bool onReadPixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width, int height,
GrColorType, void* buffer, size_t rowBytes) = 0;

View File

@ -83,36 +83,13 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload) {
int width, int height,
GrColorType srcColorType, 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, srcColorType,
kSRGBConversion, &drawPreference, &tempInfo)) {
if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface) &&
fGpu->caps()->supportedWritePixelsColorType(dstSurface->config(), srcColorType) != srcColorType) {
return false;
}
if (GrGpu::kNoDraw_DrawPreference == drawPreference) {
return this->fGpu->writePixels(dstSurface, dstProxy->origin(), left, top, width, height,
srcColorType, buffer, rowBytes);
}
// TODO: Shouldn't we be bailing here if a draw is really required instead of a copy?
// e.g. if (tempInfo.fSwizzle != "RGBA") fail.
GrSurfaceDesc desc;
desc.fWidth = width;
desc.fHeight = height;
desc.fConfig = dstProxy->config();
sk_sp<GrTexture> temp(this->fResourceProvider->createApproxTexture(
desc, GrResourceProvider::kNoPendingIO_Flag));
if (!temp) {
return false;
}
if (!fGpu->writePixels(temp.get(), dstProxy->origin(), 0, 0, width, height,
tempInfo.fWriteColorType, buffer, rowBytes)) {
return false;
}
return fGpu->copySurface(dstSurface, dstProxy->origin(), temp.get(), dstProxy->origin(),
SkIRect::MakeWH(width, height), {left, top});
return this->fGpu->writePixels(dstSurface, dstProxy->origin(), left, top, width, height,
srcColorType, buffer, rowBytes);
};
upload(wp);
}

View File

@ -648,91 +648,6 @@ sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBacken
return GrGLRenderTarget::MakeWrapped(this, surfDesc, rtIDDesc, 0);
}
////////////////////////////////////////////////////////////////////////////////
bool GrGLGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
int height, GrColorType srcColorType,
DrawPreference* drawPreference,
WritePixelTempDrawInfo* tempDrawInfo) {
// We don't want to introduce a sRGB conversion if we trigger a draw.
auto srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(dstSurface->config());
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->fWriteColorType == srcColorType);
SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == srcColorType);
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
// Don't undo a sRGB conversion introduced by our caller via an intermediate draw.
srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig);
}
if (GrColorTypeIsAlphaOnly(srcColorType)) {
srcConfigSRGBEncoded = GrSRGBEncoded::kNo;
}
if (SkToBool(dstSurface->asRenderTarget())) {
if (this->glCaps().useDrawInsteadOfAllRenderTargetWrites()) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
}
GrGLTexture* texture = static_cast<GrGLTexture*>(dstSurface->asTexture());
if (texture) {
if (GR_GL_TEXTURE_EXTERNAL == texture->target()) {
// We don't currently support writing pixels to EXTERNAL textures.
return false;
}
if (GrPixelConfigIsUnorm(texture->config()) && texture->hasBaseLevelBeenBoundToFBO() &&
this->glCaps().disallowTexSubImageForUnormConfigTexturesEverBoundToFBO() &&
(width < dstSurface->width() || height < dstSurface->height())) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
} else {
// This subclass only allows writes to textures. If the dst is not a texture we have to draw
// into it. We could use glDrawPixels on GLs that have it, but we don't today.
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
// If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target.
if (dstSurface->asRenderTarget() && dstSurface->asRenderTarget()->numColorSamples() > 1) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srcConfigSRGBEncoded);
SkASSERT(srcAsConfig != kUnknown_GrPixelConfig);
auto dstColorType = GrPixelConfigToColorType(dstSurface->config());
bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcAsConfig) == dstSurface->config();
if (configsAreRBSwaps) {
if (!this->caps()->isConfigTexturable(srcAsConfig)) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
tempDrawInfo->fWriteColorType = dstColorType;
} else if (this->glCaps().rgba8888PixelsOpsAreSlow() &&
kRGBA_8888_GrPixelConfig == srcAsConfig) {
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
tempDrawInfo->fWriteColorType = dstColorType;
} else if (kGLES_GrGLStandard == this->glStandard() &&
this->glCaps().bgraIsInternalFormat()) {
// The internal format and external formats must match texture uploads so we can't
// swizzle while uploading when BGRA is a distinct internal format.
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
tempDrawInfo->fWriteColorType = dstColorType;
}
}
if (!this->glCaps().unpackFlipYSupport() && kBottomLeft_GrSurfaceOrigin == dstOrigin) {
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
}
return true;
}
static bool check_write_and_transfer_input(GrGLTexture* glTex) {
if (!glTex) {
return false;

View File

@ -231,9 +231,6 @@ private:
// variations above, depending on whether the surface is a render target or not.
bool readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig);
bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrColorType,
DrawPreference*, WritePixelTempDrawInfo*) override;
bool onReadPixels(GrSurface*, GrSurfaceOrigin, int left, int top, int width, int height,
GrColorType, void* buffer, size_t rowBytes) override;

View File

@ -71,11 +71,6 @@ private:
GrBuffer* onCreateBuffer(size_t sizeInBytes, GrBufferType, GrAccessPattern,
const void*) override;
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin, int width, int height,
GrColorType, DrawPreference*, WritePixelTempDrawInfo*) override {
return true;
}
bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
GrColorType, void* buffer, size_t rowBytes) override {
return true;

View File

@ -31,12 +31,6 @@ public:
id<MTLDevice> device() const { return fDevice; }
bool onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
int height, GrColorType srcColorType, DrawPreference*,
WritePixelTempDrawInfo*) override {
return false;
}
bool onCopySurface(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
const SkIRect& srcRect,

View File

@ -327,54 +327,6 @@ GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPatter
return buff;
}
////////////////////////////////////////////////////////////////////////////////
bool GrVkGpu::onGetWritePixelsInfo(GrSurface* dstSurface, GrSurfaceOrigin dstOrigin, int width,
int height, GrColorType srcColorType,
DrawPreference* drawPreference,
WritePixelTempDrawInfo* tempDrawInfo) {
// We don't want to introduce a sRGB conversion if we trigger a draw.
auto srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(dstSurface->config());
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->fWriteColorType == srcColorType);
SkASSERT(GrPixelConfigToColorType(tempDrawInfo->fTempSurfaceDesc.fConfig) == srcColorType);
SkASSERT(tempDrawInfo->fSwizzle == GrSwizzle::RGBA());
// Don't undo a sRGB conversion introduced by our caller via an intermediate draw.
srcConfigSRGBEncoded = GrPixelConfigIsSRGBEncoded(tempDrawInfo->fTempSurfaceDesc.fConfig);
}
if (GrColorTypeIsAlphaOnly(srcColorType)) {
srcConfigSRGBEncoded = GrSRGBEncoded::kNo;
}
GrRenderTarget* renderTarget = dstSurface->asRenderTarget();
if (GrPixelConfigToColorType(dstSurface->config()) == srcColorType) {
// We only support writing pixels to textures. Forcing a draw lets us write to pure RTs.
if (!dstSurface->asTexture()) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
// If the dst is MSAA, we have to draw, or we'll just be writing to the resolve target.
if (renderTarget && renderTarget->numColorSamples() > 1) {
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
}
return true;
}
// Any color type change requires a draw
ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
auto srcAsConfig = GrColorTypeToPixelConfig(srcColorType, srcConfigSRGBEncoded);
SkASSERT(srcAsConfig != kUnknown_GrPixelConfig);
bool configsAreRBSwaps = GrPixelConfigSwapRAndB(srcAsConfig) == dstSurface->config();
if (!this->vkCaps().isConfigTexturable(srcAsConfig) && configsAreRBSwaps) {
tempDrawInfo->fTempSurfaceDesc.fConfig = dstSurface->config();
tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
tempDrawInfo->fWriteColorType = GrPixelConfigToColorType(dstSurface->config());
}
return true;
}
bool GrVkGpu::onWritePixels(GrSurface* surface, GrSurfaceOrigin origin, int left, int top,
int width, int height, GrColorType srcColorType,
const GrMipLevel texels[], int mipLevelCount) {

View File

@ -165,9 +165,6 @@ private:
GrBuffer* onCreateBuffer(size_t size, GrBufferType type, GrAccessPattern,
const void* data) override;
bool onGetWritePixelsInfo(GrSurface*, GrSurfaceOrigin, int width, int height, GrColorType,
DrawPreference*, WritePixelTempDrawInfo*) override;
bool onReadPixels(GrSurface* surface, GrSurfaceOrigin, int left, int top, int width, int height,
GrColorType, void* buffer, size_t rowBytes) override;