Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2313)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1613903005: Make A8 readbacks work from non-A8 surfaces (Closed) Base URL: https://skia.googlesource.com/skia.git@checksupp
Patch Set: update Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #include "GrGLGpu.h" 9 #include "GrGLGpu.h"
10 #include "GrGLGLSL.h" 10 #include "GrGLGLSL.h"
(...skipping 1986 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 1997
1998 bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig rea dConfig) { 1998 bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig rea dConfig) {
1999 if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) { 1999 if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) {
2000 return this->readPixelsSupported(rt, readConfig); 2000 return this->readPixelsSupported(rt, readConfig);
2001 } else { 2001 } else {
2002 GrPixelConfig config = surfaceForConfig->config(); 2002 GrPixelConfig config = surfaceForConfig->config();
2003 return this->readPixelsSupported(config, readConfig); 2003 return this->readPixelsSupported(config, readConfig);
2004 } 2004 }
2005 } 2005 }
2006 2006
2007 static bool requires_srgb_conversion(GrPixelConfig a, GrPixelConfig b) {
2008 if (GrPixelConfigIsSRGB(a)) {
2009 return !GrPixelConfigIsSRGB(b) && !GrPixelConfigIsAlphaOnly(b);
2010 } else if (GrPixelConfigIsSRGB(b)) {
2011 return !GrPixelConfigIsSRGB(a) && !GrPixelConfigIsAlphaOnly(a);
2012 }
2013 return false;
2014 }
2015
2007 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 2016 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
2008 GrPixelConfig readConfig, DrawPreference* draw Preference, 2017 GrPixelConfig readConfig, DrawPreference* draw Preference,
2009 ReadPixelTempDrawInfo* tempDrawInfo) { 2018 ReadPixelTempDrawInfo* tempDrawInfo) {
2010 GrRenderTarget* srcAsRT = srcSurface->asRenderTarget(); 2019 GrPixelConfig srcConfig = srcSurface->config();
2011 2020
2012 // This subclass can only read pixels from a render target. We could use glT exSubImage2D on 2021 // These settings we will always want if a temp draw is performed.
2013 // GL versions that support it but we don't today.
2014 if (!srcAsRT) {
2015 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2016 }
2017
2018 if (GrPixelConfigIsSRGB(srcSurface->config()) != GrPixelConfigIsSRGB(readCon fig)) {
2019 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2020 }
2021
2022 tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
2023 tempDrawInfo->fReadConfig = readConfig;
2024
2025 // These settings we will always want if a temp draw is performed. The confi g is set below
2026 // depending on whether we want to do a R/B swap or not.
2027 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; 2022 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
2028 tempDrawInfo->fTempSurfaceDesc.fWidth = width; 2023 tempDrawInfo->fTempSurfaceDesc.fWidth = width;
2029 tempDrawInfo->fTempSurfaceDesc.fHeight = height; 2024 tempDrawInfo->fTempSurfaceDesc.fHeight = height;
2030 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 2025 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
2031 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 2026 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
2032 tempDrawInfo->fUseExactScratch = this->glCaps().partialFBOReadIsSlow(); 2027 tempDrawInfo->fUseExactScratch = this->glCaps().partialFBOReadIsSlow();
2033 2028
2034 // Start off assuming that any temp draw should be to the readConfig, then c heck if that will 2029 // For now assume no swizzling, we may change that below.
2035 // be inefficient. 2030 tempDrawInfo->fSwizzle = GrSwizzle::RGBA();
2036 GrPixelConfig srcConfig = srcSurface->config(); 2031
2037 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; 2032 // Depends on why we need/want a temp draw. Start off assuming no change, th e surface we read
2033 // from will be srcConfig and we will read readConfig pixels from it.
2034 // Not that if we require a draw and return a non-renderable format for the temp surface the
2035 // base class will fail for us.
2036 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2037 tempDrawInfo->fReadConfig = readConfig;
2038
2039 if (requires_srgb_conversion(srcConfig, readConfig)) {
2040 // Draw to do srgb to linear conversion or vice versa.
2041 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2042 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
egdaniel 2016/01/25 21:28:24 so not 100% sure how the srgb coversion works, but
bsalomon 2016/01/25 21:45:17 Yes, the conversion to or from sRGB happens during
2043 tempDrawInfo->fReadConfig = readConfig;
2044 return true;
2045 }
2046
2047 GrRenderTarget* srcAsRT = srcSurface->asRenderTarget();
2048 if (!srcAsRT) {
2049 // For now keep assuming the draw is not a format transformation, just a draw to get to a
2050 // RT. We may add additional transformations below.
2051 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2052 }
2038 2053
2039 if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig && 2054 if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig &&
2040 this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelCo nfig)) { 2055 this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelCo nfig)) {
2041 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig; 2056 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
2042 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2057 tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2043 tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig; 2058 tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig;
2044 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2059 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2045 } else if (kMesa_GrGLDriver == this->glContext().driver() && 2060 } else if (kMesa_GrGLDriver == this->glContext().driver() &&
2046 GrBytesPerPixel(readConfig) == 4 && 2061 GrBytesPerPixel(readConfig) == 4 &&
2047 GrPixelConfigSwapRAndB(readConfig) == srcConfig && 2062 GrPixelConfigSwapRAndB(readConfig) == srcConfig &&
2048 this->readPixelsSupported(srcSurface, srcConfig)) { 2063 this->readPixelsSupported(srcSurface, srcConfig)) {
2049 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surf ace and vice-versa. 2064 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surf ace and vice-versa.
2050 // Better to do a draw with a R/B swap and then read as the original con fig. 2065 // Better to do a draw with a R/B swap and then read as the original con fig.
2051 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 2066 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
2052 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2067 tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2053 tempDrawInfo->fReadConfig = srcConfig; 2068 tempDrawInfo->fReadConfig = srcConfig;
2054 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2069 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2055 } else if (!this->readPixelsSupported(srcSurface, readConfig)) { 2070 } else if (!this->readPixelsSupported(srcSurface, readConfig)) {
2056 if (readConfig == kBGRA_8888_GrPixelConfig && 2071 if (readConfig == kBGRA_8888_GrPixelConfig &&
2057 this->glCaps().isConfigRenderable(kRGBA_8888_GrPixelConfig, false) & & 2072 this->glCaps().isConfigRenderable(kRGBA_8888_GrPixelConfig, false) & &
2058 this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPix elConfig)) { 2073 this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPix elConfig)) {
2059 2074 // We're trying to read BGRA but it's not supported. If RGBA is rend erable and
2075 // we can read it back, then do a swizzling draw to a RGBA and read it back (which
2076 // will effectively be BGRA).
2060 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; 2077 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
2061 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); 2078 tempDrawInfo->fSwizzle = GrSwizzle::BGRA();
2062 tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; 2079 tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig;
2063 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 2080 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
2081 } else if (readConfig == kAlpha_8_GrPixelConfig) {
2082 // onReadPixels implements a fallback for cases where we are want to read kAlpha_8,
2083 // it's unsupported, but 32bit RGBA reads are supported.
2084 // Don't attempt to do any srgb conversions since we only care about alpha.
2085 GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig;
2086 if (GrPixelConfigIsSRGB(srcSurface->config())) {
2087 cpuTempConfig = kSRGBA_8888_GrPixelConfig;
2088 }
2089 if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) {
2090 // If we can't read RGBA from the src try to draw to a kRGBA_888 8 (or kSRGBA_8888)
2091 // first and then onReadPixels will read that to a 32bit tempora ry buffer.
2092 if (this->caps()->isConfigRenderable(cpuTempConfig, false)) {
2093 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPrefe rence);
2094 tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig;
2095 tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig;
2096 } else {
2097 return false;
2098 }
2099 } else {
2100 SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig);
2101 SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig);
2102 }
2064 } else { 2103 } else {
2065 return false; 2104 return false;
2066 } 2105 }
2067 } 2106 }
2068 2107
2069 if (srcAsRT && 2108 if (srcAsRT &&
2070 read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, height, read Config, rowBytes)) { 2109 read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, height, read Config, rowBytes)) {
2071 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); 2110 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference);
2072 } 2111 }
2073 2112
2074 return true; 2113 return true;
2075 } 2114 }
2076 2115
2077 bool GrGLGpu::onReadPixels(GrSurface* surface, 2116 bool GrGLGpu::onReadPixels(GrSurface* surface,
2078 int left, int top, 2117 int left, int top,
2079 int width, int height, 2118 int width, int height,
2080 GrPixelConfig config, 2119 GrPixelConfig config,
2081 void* buffer, 2120 void* buffer,
2082 size_t rowBytes) { 2121 size_t rowBytes) {
2083 SkASSERT(surface); 2122 SkASSERT(surface);
2084 2123
2085 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(surface->asRenderTarg et()); 2124 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(surface->asRenderTarg et());
2086 if (!tgt) { 2125 if (!tgt) {
2087 return false; 2126 return false;
2088 } 2127 }
2089 2128
2090 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels. 2129 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
2091 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { 2130 if (requires_srgb_conversion(surface->config(), config)) {
2092 return false; 2131 return false;
2093 } 2132 }
2094 2133
2134 // We have a special case fallback for reading eight bit alpha. We will read back all four 8
2135 // bit channels as RGBA and then extract A.
2136 if (!this->readPixelsSupported(tgt, config)) {
2137 // Don't attempt to do any srgb conversions since we only care about alp ha.
2138 GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig;
2139 if (GrPixelConfigIsSRGB(tgt->config())) {
2140 tempConfig = kSRGBA_8888_GrPixelConfig;
2141 }
2142 if (kAlpha_8_GrPixelConfig == config &&
2143 this->readPixelsSupported(surface, tempConfig)) {
egdaniel 2016/01/25 21:28:24 just for symmetry can we use tgt instead of surfac
bsalomon 2016/01/25 21:45:17 Done, also renamed tgt to renderTarget.
2144 SkAutoTDeleteArray<uint32_t> temp(new uint32_t[width * height * 4]);
2145 if (this->onReadPixels(surface, left, top, width, height, tempConfig , temp.get(),
2146 width*4)) {
2147 uint8_t* dst = reinterpret_cast<uint8_t*>(buffer);
2148 for (int j = 0; j < height; ++j) {
2149 for (int i = 0; i < width; ++i) {
2150 dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >> 24;
2151 }
2152 }
2153 return true;
2154 }
2155 }
2156 return false;
2157 }
2158
2095 GrGLenum externalFormat; 2159 GrGLenum externalFormat;
2096 GrGLenum externalType; 2160 GrGLenum externalType;
2097 if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &external Format, 2161 if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &external Format,
2098 &externalType)) { 2162 &externalType)) {
2099 return false; 2163 return false;
2100 } 2164 }
2101 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 2165 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
2102 2166
2103 // resolve the render target if necessary 2167 // resolve the render target if necessary
2104 switch (tgt->getResolveType()) { 2168 switch (tgt->getResolveType()) {
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after
3556 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || 3620 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
3557 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { 3621 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
3558 copyParams->fFilter = GrTextureParams::kNone_FilterMode; 3622 copyParams->fFilter = GrTextureParams::kNone_FilterMode;
3559 copyParams->fWidth = texture->width(); 3623 copyParams->fWidth = texture->width();
3560 copyParams->fHeight = texture->height(); 3624 copyParams->fHeight = texture->height();
3561 return true; 3625 return true;
3562 } 3626 }
3563 } 3627 }
3564 return false; 3628 return false;
3565 } 3629 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698