diff options
author | 2018-02-14 13:53:55 -0500 | |
---|---|---|
committer | 2018-02-14 19:58:14 +0000 | |
commit | 9b009bb069aa81425438d5403a1a29f2d047f77f (patch) | |
tree | a3ff6b83971d9c1564d1de84e219a187f703ed8b /src/gpu/gl/GrGLGpu.cpp | |
parent | 95edb43251e8fcef4286c91d334c3259940a0095 (diff) |
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>
Diffstat (limited to 'src/gpu/gl/GrGLGpu.cpp')
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 130 |
1 files changed, 50 insertions, 80 deletions
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 6563215acd..3cae7d3f3c 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -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]); |