Remove sRGB config checks based on color space

All of the restrictions/assumptions that led to this code are gone,
so we can always use appropriate color space.

For the YUV provider, if/when we re-introduce 8888 sRGB, the color
space will have a linear transfer function, so the color space
xform will automatically do what was happening here. That removes
the last usage of framebuffer sRGB control, so we can remove all
kinds of GrPaint and GrPipeline plumbing for that feature.

Change-Id: I24af1d498dbc75210f92f8c61b10aa31eec022f6
Reviewed-on: https://skia-review.googlesource.com/138986
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2018-07-02 15:21:46 -04:00 committed by Skia Commit-Bot
parent 2f046f1f52
commit 9aa30c6ee0
21 changed files with 26 additions and 131 deletions

View File

@ -91,17 +91,9 @@ static void convolve_gaussian_1d(GrRenderTargetContext* renderTargetContext,
SkRect::Make(dstRect), localMatrix);
}
static GrPixelConfig get_blur_config(GrTextureProxy* proxy, SkColorSpace* cs) {
static GrPixelConfig get_blur_config(GrTextureProxy* proxy) {
GrPixelConfig config = proxy->config();
if (GrPixelConfigIsSRGB(config) && !cs) {
// If the context doesn't have sRGB write control, and we make an sRGB RTC, we won't be
// able to suppress the linear -> sRGB conversion out of the shader. Not all GL drivers
// have that feature, and Vulkan is missing it entirely. To keep things simple, switch to
// a non-sRGB destination, to ensure correct blurring behavior.
config = kRGBA_8888_GrPixelConfig;
}
SkASSERT(kBGRA_8888_GrPixelConfig == config || kRGBA_8888_GrPixelConfig == config ||
kRGB_888_GrPixelConfig == config || kRGBA_4444_GrPixelConfig == config ||
kRGB_565_GrPixelConfig == config || kSRGBA_8888_GrPixelConfig == config ||
@ -123,7 +115,7 @@ static sk_sp<GrRenderTargetContext> convolve_gaussian_2d(GrContext* context,
const SkImageInfo& dstII,
SkBackingFit dstFit) {
GrPixelConfig config = get_blur_config(proxy.get(), dstII.colorSpace());
GrPixelConfig config = get_blur_config(proxy.get());
sk_sp<GrRenderTargetContext> renderTargetContext;
renderTargetContext = context->contextPriv().makeDeferredRenderTargetContext(
@ -163,7 +155,7 @@ static sk_sp<GrRenderTargetContext> convolve_gaussian(GrContext* context,
SkBackingFit fit) {
SkASSERT(srcRect.width() <= dstII.width() && srcRect.height() <= dstII.height());
GrPixelConfig config = get_blur_config(proxy.get(), dstII.colorSpace());
GrPixelConfig config = get_blur_config(proxy.get());
sk_sp<GrRenderTargetContext> dstRenderTargetContext;
dstRenderTargetContext = context->contextPriv().makeDeferredRenderTargetContext(
@ -262,7 +254,7 @@ static sk_sp<GrTextureProxy> decimate(GrContext* context,
SkASSERT(SkIsPow2(scaleFactorX) && SkIsPow2(scaleFactorY));
SkASSERT(scaleFactorX > 1 || scaleFactorY > 1);
GrPixelConfig config = get_blur_config(src.get(), dstII.colorSpace());
GrPixelConfig config = get_blur_config(src.get());
SkIRect srcRect;
if (GrTextureDomain::kIgnore_Mode == mode) {
@ -381,7 +373,7 @@ static sk_sp<GrRenderTargetContext> reexpand(GrContext* context,
srcRenderTargetContext = nullptr; // no longer needed
GrPixelConfig config = get_blur_config(srcProxy.get(), dstII.colorSpace());
GrPixelConfig config = get_blur_config(srcProxy.get());
sk_sp<GrRenderTargetContext> dstRenderTargetContext =
context->contextPriv().makeDeferredRenderTargetContext(fit, dstII.width(), dstII.height(),
@ -436,7 +428,7 @@ sk_sp<GrRenderTargetContext> GaussianBlur(GrContext* context,
SkBackingFit fit) {
SkASSERT(context);
const GrPixelConfig config = get_blur_config(srcProxy.get(), colorSpace.get());
const GrPixelConfig config = get_blur_config(srcProxy.get());
SkColorType ct;
if (!GrPixelConfigToColorType(config, &ct)) {
return nullptr;

View File

@ -407,12 +407,8 @@ public:
if (!rec) {
return false;
}
sk_sp<SkColorSpace> colorSpace;
if (GrPixelConfigIsSRGB(fTextureProxy->config())) {
colorSpace = SkColorSpace::MakeSRGB();
}
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
fTextureProxy, std::move(colorSpace));
fTextureProxy, fColorSpace);
if (!sContext) {
return false;
}

View File

@ -15,7 +15,6 @@ GrPaint::GrPaint(const GrPaint& that)
: fXPFactory(that.fXPFactory)
, fColorFragmentProcessors(that.fColorFragmentProcessors.count())
, fCoverageFragmentProcessors(that.fCoverageFragmentProcessors.count())
, fDisableOutputConversionToSRGB(that.fDisableOutputConversionToSRGB)
, fTrivial(that.fTrivial)
, fColor(that.fColor) {
for (int i = 0; i < that.fColorFragmentProcessors.count(); ++i) {

View File

@ -55,13 +55,6 @@ public:
*/
GrColor getColor() const { return fColor.toGrColor(); }
/**
* Should shader output conversion from linear to sRGB be disabled.
* Only relevant if the destination is sRGB. Defaults to false.
*/
void setDisableOutputConversionToSRGB(bool srgb) { fDisableOutputConversionToSRGB = srgb; }
bool getDisableOutputConversionToSRGB() const { return fDisableOutputConversionToSRGB; }
void setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory = xpFactory;
fTrivial &= !SkToBool(xpFactory);
@ -138,7 +131,6 @@ private:
const GrXPFactory* fXPFactory = nullptr;
SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fColorFragmentProcessors;
SkSTArray<2, std::unique_ptr<GrFragmentProcessor>> fCoverageFragmentProcessors;
bool fDisableOutputConversionToSRGB = false;
bool fTrivial = true;
GrColor4f fColor = GrColor4f::OpaqueWhite();
};

View File

@ -52,18 +52,8 @@ public:
* Modifies the vertex shader so that vertices will be positioned at pixel centers.
*/
kSnapVerticesToPixelCenters_Flag = 0x2,
/** Disables conversion to sRGB from linear when writing to a sRGB destination. */
kDisableOutputConversionToSRGB_Flag = 0x4,
};
static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
uint32_t flags = 0;
if (paint.getDisableOutputConversionToSRGB()) {
flags |= kDisableOutputConversionToSRGB_Flag;
}
return flags;
}
enum ScissorState : bool {
kEnabled = true,
kDisabled = false
@ -189,9 +179,6 @@ public:
bool snapVerticesToPixelCenters() const {
return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
}
bool getDisableOutputConversionToSRGB() const {
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
}
bool hasStencilClip() const {
return SkToBool(fFlags & kHasStencilClip_Flag);
}
@ -211,9 +198,6 @@ public:
if (flags & GrPipeline::kHWAntialias_Flag) {
result.append("HW Antialiasing enabled.\n");
}
if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) {
result.append("Disable output conversion to sRGB.\n");
}
return result;
}
return SkString("No pipeline flags\n");

View File

@ -18,7 +18,6 @@
#include "SkRefCnt.h"
#include "SkResourceCache.h"
#include "SkYUVPlanesCache.h"
#include "effects/GrSRGBEffect.h"
#include "effects/GrYUVtoRGBEffect.h"
sk_sp<SkCachedData> init_provider(GrYUVProvider* provider, SkYUVPlanesCache::Info* yuvInfo,
@ -128,21 +127,6 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS
yuvInfo.fSizeInfo.fSizes, yuvInfo.fColorSpace, false);
paint.addColorFragmentProcessor(std::move(yuvToRgbProcessor));
// If we're decoding an sRGB image, the result of our linear math on the YUV planes is already
// in sRGB. (The encoding is just math on bytes, with no concept of color spaces.) So, we need
// to output the results of that math directly to the buffer that we will then consider sRGB.
// If we have sRGB write control, we can just tell the HW not to do the Linear -> sRGB step.
// Otherwise, we do our shader math to go from YUV -> sRGB, manually convert sRGB -> Linear,
// then let the HW convert Linear -> sRGB.
if (GrPixelConfigIsSRGB(desc.fConfig)) {
if (ctx->contextPriv().caps()->srgbWriteControl()) {
paint.setDisableOutputConversionToSRGB(true);
} else {
paint.addColorFragmentProcessor(GrSRGBEffect::Make(GrSRGBEffect::Mode::kSRGBToLinear,
GrSRGBEffect::Alpha::kOpaque));
}
}
// If the caller expects the pixels in a different color space than the one from the image,
// apply a color conversion to do this.
std::unique_ptr<GrFragmentProcessor> colorConversionProcessor =

View File

@ -65,7 +65,6 @@ GrCCDrawPathsOp::GrCCDrawPathsOp(const SkMatrix& m, const GrShape& shape,
GrPaint&& paint)
: GrDrawOp(ClassID())
, fViewMatrixIfUsingLocalCoords(has_coord_transforms(paint) ? m : SkMatrix::I())
, fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
, fDraws(m, shape, shapeDevIBounds, maskDevIBounds, maskVisibility, paint.getColor())
, fProcessors(std::move(paint)) { // Paint must be moved after fetching its color above.
SkDEBUGCODE(fBaseInstance = -1);
@ -125,7 +124,7 @@ bool GrCCDrawPathsOp::onCombineIfPossible(GrOp* op, const GrCaps&) {
SkASSERT(!that->fOwningPerOpListPaths || that->fOwningPerOpListPaths == fOwningPerOpListPaths);
SkASSERT(that->fNumDraws);
if (fSRGBFlags != that->fSRGBFlags || fProcessors != that->fProcessors ||
if (fProcessors != that->fProcessors ||
fViewMatrixIfUsingLocalCoords != that->fViewMatrixIfUsingLocalCoords) {
return false;
}
@ -332,7 +331,6 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState) {
}
GrPipeline::InitArgs initArgs;
initArgs.fFlags = fSRGBFlags;
initArgs.fProxy = flushState->drawOpArgs().fProxy;
initArgs.fCaps = &flushState->caps();
initArgs.fResourceProvider = flushState->resourceProvider();

View File

@ -84,7 +84,6 @@ private:
void recordInstance(const GrTextureProxy* atlasProxy, int instanceIdx);
const SkMatrix fViewMatrixIfUsingLocalCoords;
const uint32_t fSRGBFlags;
struct SingleDraw {
SingleDraw(const SkMatrix&, const GrShape&, const SkIRect& shapeDevIBounds,

View File

@ -1733,7 +1733,7 @@ bool GrGLGpu::flushGLState(const GrPrimitiveProcessor& primProc,
// This must come after textures are flushed because a texture may need
// to be msaa-resolved (which will modify bound FBO state).
this->flushRenderTarget(glRT, pipeline.getDisableOutputConversionToSRGB());
this->flushRenderTarget(glRT);
return true;
}
@ -2156,17 +2156,17 @@ GrGpuTextureCommandBuffer* GrGLGpu::createCommandBuffer(GrTexture* texture,
}
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin,
const SkIRect& bounds, bool disableSRGB) {
this->flushRenderTargetNoColorWrites(target, disableSRGB);
const SkIRect& bounds) {
this->flushRenderTargetNoColorWrites(target);
this->didWriteToSurface(target, origin, &bounds);
}
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, bool disableSRGB) {
this->flushRenderTargetNoColorWrites(target, disableSRGB);
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target) {
this->flushRenderTargetNoColorWrites(target);
this->didWriteToSurface(target, kTopLeft_GrSurfaceOrigin, nullptr);
}
void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool disableSRGB) {
void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target) {
SkASSERT(target);
GrGpuResource::UniqueID rtID = target->uniqueID();
if (fHWBoundRenderTargetUniqueID != rtID) {
@ -2192,7 +2192,7 @@ void GrGLGpu::flushRenderTargetNoColorWrites(GrGLRenderTarget* target, bool disa
}
if (this->glCaps().srgbWriteControl()) {
this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB);
this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()));
}
}

View File

@ -346,12 +346,11 @@ private:
// The passed bounds contains the render target's color values that will subsequently be
// written.
void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds,
bool disableSRGB = false);
void flushRenderTarget(GrGLRenderTarget*, GrSurfaceOrigin, const SkIRect& bounds);
// This version has an implicit bounds of the entire render target.
void flushRenderTarget(GrGLRenderTarget*, bool disableSRGB = false);
void flushRenderTarget(GrGLRenderTarget*);
// This version can be used when the render target's colors will not be written.
void flushRenderTargetNoColorWrites(GrGLRenderTarget*, bool disableSRGB = false);
void flushRenderTargetNoColorWrites(GrGLRenderTarget*);
// Need not be called if flushRenderTarget is used.
void flushViewport(const GrGLIRect&);

View File

@ -297,8 +297,9 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) {
}
SkASSERT(proxies[0]);
auto pipe =
target->makePipeline(fSRGBFlags, std::move(fProcessors), target->detachAppliedClip());
static const uint32_t kPipelineFlags = 0;
auto pipe = target->makePipeline(kPipelineFlags, std::move(fProcessors),
target->detachAppliedClip());
FlushInfo flushInfo;
flushInfo.fPipeline = pipe.fPipeline;

View File

@ -101,7 +101,6 @@ private:
GrAtlasTextOp(GrPaint&& paint)
: INHERITED(ClassID())
, fGeoDataAllocSize(kMinGeometryAllocated)
, fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
, fProcessors(std::move(paint)) {}
struct FlushInfo {
@ -158,7 +157,6 @@ private:
SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
int fGeoDataAllocSize;
uint32_t fSRGBFlags;
GrProcessorSet fProcessors;
struct {
uint32_t fUsesLocalCoords : 1;

View File

@ -335,7 +335,6 @@ private:
bool fullDash, const GrUserStencilSettings* stencilSettings)
: INHERITED(ClassID())
, fColor(paint.getColor())
, fDisableSRGBOutputConversion(paint.getDisableOutputConversionToSRGB())
, fFullDash(fullDash)
, fCap(cap)
, fAAMode(aaMode)
@ -694,9 +693,6 @@ private:
if (AAMode::kCoverageWithMSAA == fAAMode) {
pipelineFlags |= GrPipeline::kHWAntialias_Flag;
}
if (fDisableSRGBOutputConversion) {
pipelineFlags |= GrPipeline::kDisableOutputConversionToSRGB_Flag;
}
auto pipe = target->makePipeline(pipelineFlags, std::move(fProcessorSet),
target->detachAppliedClip());
helper.recordDraw(target, gp.get(), pipe.fPipeline, pipe.fFixedDynamicState);
@ -749,7 +745,6 @@ private:
SkSTArray<1, LineData, true> fLines;
GrColor fColor;
bool fDisableSRGBOutputConversion : 1;
bool fDisallowCombineOnTouchOrOverlap : 1;
bool fUsesLocalCoords : 1;
bool fFullDash : 1;

View File

@ -19,7 +19,6 @@ GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix,
, fInputColor(paint.getColor())
, fFillType(fill)
, fAAType(aaType)
, fPipelineSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint))
, fProcessorSet(std::move(paint)) {}
SkString GrDrawPathOp::dumpInfo() const {
@ -40,7 +39,6 @@ GrPipeline::InitArgs GrDrawPathOpBase::pipelineInitArgs(const GrOpFlushState& st
0xffff>()
};
GrPipeline::InitArgs args;
args.fFlags = fPipelineSRGBFlags;
if (GrAATypeIsHW(fAAType)) {
args.fFlags |= GrPipeline::kHWAntialias_Flag;
}

View File

@ -45,7 +45,6 @@ protected:
GrPathRendering::FillType fillType() const { return fFillType; }
const GrProcessorSet& processors() const { return fProcessorSet; }
GrProcessorSet detachProcessors() { return std::move(fProcessorSet); }
uint32_t pipelineSRGBFlags() const { return fPipelineSRGBFlags; }
inline GrPipeline::InitArgs pipelineInitArgs(const GrOpFlushState&);
const GrProcessorSet::Analysis& doProcessorAnalysis(const GrCaps& caps,
const GrAppliedClip* clip,
@ -68,7 +67,6 @@ private:
GrProcessorSet::Analysis fAnalysis;
GrPathRendering::FillType fFillType;
GrAAType fAAType;
uint32_t fPipelineSRGBFlags;
GrProcessorSet fProcessorSet;
typedef GrDrawOp INHERITED;

View File

@ -14,7 +14,7 @@
GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(const MakeArgs& args, GrAAType aaType,
Flags flags)
: fProcessors(args.fProcessorSet)
, fPipelineFlags(args.fSRGBFlags)
, fPipelineFlags(0)
, fAAType((int)aaType)
, fRequiresDstTexture(false)
, fUsesLocalCoords(false)

View File

@ -99,7 +99,6 @@ public:
MakeArgs() = default;
GrProcessorSet* fProcessorSet;
uint32_t fSRGBFlags;
friend class GrSimpleMeshDrawOpHelper;
};
@ -181,7 +180,6 @@ std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrContext* con
GrOpMemoryPool* pool = context->contextPriv().opMemoryPool();
MakeArgs makeArgs;
makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint);
GrColor color = paint.getColor();
if (paint.isTrivial()) {

View File

@ -230,29 +230,8 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
flags = GrContextPriv::kUnpremul_PixelOpsFlag;
}
// This hack allows us to call makeNonTextureImage on images with arbitrary color spaces.
// Otherwise, we'll be unable to create a render target context.
// TODO: This shouldn't be necessary - we need more robust support for images (and surfaces)
// with arbitrary color spaces. Unfortunately, this is one spot where we go from image to
// surface (rather than the opposite), and our lenient image rules break our (currently) more
// strict surface rules.
// GrSurfaceContext::readPixels does not make use of the context's color space. However, we
// don't allow creating a surface context for a sRGB GrPixelConfig unless the color space has
// sRGB gamma. So we choose null for non-SRGB GrPixelConfigs and sRGB for sRGB GrPixelConfigs.
sk_sp<SkColorSpace> surfaceColorSpace = fColorSpace;
if (!flags) {
if (!dstInfo.colorSpace() ||
SkColorSpace::Equals(fColorSpace.get(), dstInfo.colorSpace())) {
if (GrPixelConfigIsSRGB(fProxy->config())) {
surfaceColorSpace = SkColorSpace::MakeSRGB();
} else {
surfaceColorSpace = nullptr;
}
}
}
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
fProxy, surfaceColorSpace);
fProxy, fColorSpace);
if (!sContext) {
return false;
}

View File

@ -248,12 +248,6 @@ static void set_random_color_coverage_stages(GrPaint* paint,
}
}
static void set_random_state(GrPaint* paint, SkRandom* random) {
if (random->nextBool()) {
paint->setDisableOutputConversionToSRGB(true);
}
}
#endif
#if !GR_TEST_UTILS
@ -310,7 +304,6 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int ma
GrProcessorTestData ptd(&random, context, renderTargetContext.get(), proxies);
set_random_color_coverage_stages(&paint, &ptd, maxStages, maxLevels);
set_random_xpf(&paint, &ptd);
set_random_state(&paint, &random);
GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
}
// Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)

View File

@ -151,10 +151,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info)
for (int c = 0; c <= kLast_GrPixelConfig; ++c) {
desc.fConfig = static_cast<GrPixelConfig>(c);
sk_sp<SkColorSpace> colorSpace;
if (GrPixelConfigIsSRGB(desc.fConfig)) {
colorSpace = SkColorSpace::MakeSRGB();
}
if (!context->contextPriv().caps()->isConfigTexturable(desc.fConfig)) {
continue;
}
@ -176,7 +172,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info)
continue;
}
auto texCtx = context->contextPriv().makeWrappedSurfaceContext(
std::move(proxy), colorSpace);
std::move(proxy));
SkImageInfo info = SkImageInfo::Make(
kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
@ -201,7 +197,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info)
// Try creating the texture as a deferred proxy.
for (int i = 0; i < 2; ++i) {
auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes, colorSpace);
desc, origin, GrMipMapped::kNo, fit, SkBudgeted::kYes);
if (!surfCtx) {
continue;
}

View File

@ -191,12 +191,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadWriteAlpha, reporter, ctxInfo) {
continue;
}
sk_sp<SkColorSpace> colorSpace;
if (GrPixelConfigIsSRGB(proxy->config())) {
colorSpace = SkColorSpace::MakeSRGB();
}
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
std::move(proxy), std::move(colorSpace));
std::move(proxy));
for (auto rowBytes : kRowBytes) {
size_t nonZeroRowBytes = rowBytes ? rowBytes : X_SIZE;