OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |