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 if (!this->readPixelsSupported(readConfig, readConfig)) { |
| 2041 return false; |
| 2042 } |
| 2043 // Draw to do srgb to linear conversion or vice versa. |
| 2044 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| 2045 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; |
| 2046 tempDrawInfo->fReadConfig = readConfig; |
| 2047 return true; |
| 2048 } |
| 2049 |
| 2050 GrRenderTarget* srcAsRT = srcSurface->asRenderTarget(); |
| 2051 if (!srcAsRT) { |
| 2052 // For now keep assuming the draw is not a format transformation, just a
draw to get to a |
| 2053 // RT. We may add additional transformations below. |
| 2054 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| 2055 } |
2038 | 2056 |
2039 if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig ==
readConfig && | 2057 if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig ==
readConfig && |
2040 this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelCo
nfig)) { | 2058 this->readPixelsSupported(kBGRA_8888_GrPixelConfig, kBGRA_8888_GrPixelCo
nfig)) { |
2041 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig; | 2059 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig; |
2042 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); | 2060 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
2043 tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig; | 2061 tempDrawInfo->fReadConfig = kBGRA_8888_GrPixelConfig; |
2044 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); | 2062 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
2045 } else if (kMesa_GrGLDriver == this->glContext().driver() && | 2063 } else if (kMesa_GrGLDriver == this->glContext().driver() && |
2046 GrBytesPerPixel(readConfig) == 4 && | 2064 GrBytesPerPixel(readConfig) == 4 && |
2047 GrPixelConfigSwapRAndB(readConfig) == srcConfig && | 2065 GrPixelConfigSwapRAndB(readConfig) == srcConfig && |
2048 this->readPixelsSupported(srcSurface, srcConfig)) { | 2066 this->readPixelsSupported(srcSurface, srcConfig)) { |
2049 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA surf
ace and vice-versa. | 2067 // 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. | 2068 // Better to do a draw with a R/B swap and then read as the original con
fig. |
2051 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; | 2069 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; |
2052 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); | 2070 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
2053 tempDrawInfo->fReadConfig = srcConfig; | 2071 tempDrawInfo->fReadConfig = srcConfig; |
2054 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); | 2072 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
2055 } else if (!this->readPixelsSupported(srcSurface, readConfig)) { | 2073 } else if (!this->readPixelsSupported(srcSurface, readConfig)) { |
2056 if (readConfig == kBGRA_8888_GrPixelConfig && | 2074 if (readConfig == kBGRA_8888_GrPixelConfig && |
2057 this->glCaps().isConfigRenderable(kRGBA_8888_GrPixelConfig, false) &
& | 2075 this->glCaps().isConfigRenderable(kRGBA_8888_GrPixelConfig, false) &
& |
2058 this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPix
elConfig)) { | 2076 this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPix
elConfig)) { |
2059 | 2077 // We're trying to read BGRA but it's not supported. If RGBA is rend
erable and |
| 2078 // we can read it back, then do a swizzling draw to a RGBA and read
it back (which |
| 2079 // will effectively be BGRA). |
2060 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; | 2080 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; |
2061 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); | 2081 tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
2062 tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; | 2082 tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; |
2063 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); | 2083 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
| 2084 } else if (readConfig == kAlpha_8_GrPixelConfig) { |
| 2085 // onReadPixels implements a fallback for cases where we are want to
read kAlpha_8, |
| 2086 // it's unsupported, but 32bit RGBA reads are supported. |
| 2087 // Don't attempt to do any srgb conversions since we only care about
alpha. |
| 2088 GrPixelConfig cpuTempConfig = kRGBA_8888_GrPixelConfig; |
| 2089 if (GrPixelConfigIsSRGB(srcSurface->config())) { |
| 2090 cpuTempConfig = kSRGBA_8888_GrPixelConfig; |
| 2091 } |
| 2092 if (!this->readPixelsSupported(srcSurface, cpuTempConfig)) { |
| 2093 // If we can't read RGBA from the src try to draw to a kRGBA_888
8 (or kSRGBA_8888) |
| 2094 // first and then onReadPixels will read that to a 32bit tempora
ry buffer. |
| 2095 if (this->caps()->isConfigRenderable(cpuTempConfig, false)) { |
| 2096 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPrefe
rence); |
| 2097 tempDrawInfo->fTempSurfaceDesc.fConfig = cpuTempConfig; |
| 2098 tempDrawInfo->fReadConfig = kAlpha_8_GrPixelConfig; |
| 2099 } else { |
| 2100 return false; |
| 2101 } |
| 2102 } else { |
| 2103 SkASSERT(tempDrawInfo->fTempSurfaceDesc.fConfig == srcConfig); |
| 2104 SkASSERT(tempDrawInfo->fReadConfig == kAlpha_8_GrPixelConfig); |
| 2105 } |
2064 } else { | 2106 } else { |
2065 return false; | 2107 return false; |
2066 } | 2108 } |
2067 } | 2109 } |
2068 | 2110 |
2069 if (srcAsRT && | 2111 if (srcAsRT && |
2070 read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, height, read
Config, rowBytes)) { | 2112 read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, height, read
Config, rowBytes)) { |
2071 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); | 2113 ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
2072 } | 2114 } |
2073 | 2115 |
2074 return true; | 2116 return true; |
2075 } | 2117 } |
2076 | 2118 |
2077 bool GrGLGpu::onReadPixels(GrSurface* surface, | 2119 bool GrGLGpu::onReadPixels(GrSurface* surface, |
2078 int left, int top, | 2120 int left, int top, |
2079 int width, int height, | 2121 int width, int height, |
2080 GrPixelConfig config, | 2122 GrPixelConfig config, |
2081 void* buffer, | 2123 void* buffer, |
2082 size_t rowBytes) { | 2124 size_t rowBytes) { |
2083 SkASSERT(surface); | 2125 SkASSERT(surface); |
2084 | 2126 |
2085 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(surface->asRenderTarg
et()); | 2127 GrGLRenderTarget* renderTarget = static_cast<GrGLRenderTarget*>(surface->asR
enderTarget()); |
2086 if (!tgt) { | 2128 if (!renderTarget) { |
2087 return false; | 2129 return false; |
2088 } | 2130 } |
2089 | 2131 |
2090 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi
xels. | 2132 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi
xels. |
2091 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) { | 2133 if (requires_srgb_conversion(surface->config(), config)) { |
| 2134 return false; |
| 2135 } |
| 2136 |
| 2137 // We have a special case fallback for reading eight bit alpha. We will read
back all four 8 |
| 2138 // bit channels as RGBA and then extract A. |
| 2139 if (!this->readPixelsSupported(renderTarget, config)) { |
| 2140 // Don't attempt to do any srgb conversions since we only care about alp
ha. |
| 2141 GrPixelConfig tempConfig = kRGBA_8888_GrPixelConfig; |
| 2142 if (GrPixelConfigIsSRGB(renderTarget->config())) { |
| 2143 tempConfig = kSRGBA_8888_GrPixelConfig; |
| 2144 } |
| 2145 if (kAlpha_8_GrPixelConfig == config && |
| 2146 this->readPixelsSupported(renderTarget, tempConfig)) { |
| 2147 SkAutoTDeleteArray<uint32_t> temp(new uint32_t[width * height * 4]); |
| 2148 if (this->onReadPixels(renderTarget, left, top, width, height, tempC
onfig, temp.get(), |
| 2149 width*4)) { |
| 2150 uint8_t* dst = reinterpret_cast<uint8_t*>(buffer); |
| 2151 for (int j = 0; j < height; ++j) { |
| 2152 for (int i = 0; i < width; ++i) { |
| 2153 dst[j*rowBytes + i] = (0xFF000000U & temp[j*width+i]) >>
24; |
| 2154 } |
| 2155 } |
| 2156 return true; |
| 2157 } |
| 2158 } |
2092 return false; | 2159 return false; |
2093 } | 2160 } |
2094 | 2161 |
2095 GrGLenum externalFormat; | 2162 GrGLenum externalFormat; |
2096 GrGLenum externalType; | 2163 GrGLenum externalType; |
2097 if (!this->glCaps().getReadPixelsFormat(surface->config(), config, &external
Format, | 2164 if (!this->glCaps().getReadPixelsFormat(renderTarget->config(), config, &ext
ernalFormat, |
2098 &externalType)) { | 2165 &externalType)) { |
2099 return false; | 2166 return false; |
2100 } | 2167 } |
2101 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); | 2168 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); |
2102 | 2169 |
2103 // resolve the render target if necessary | 2170 // resolve the render target if necessary |
2104 switch (tgt->getResolveType()) { | 2171 switch (renderTarget->getResolveType()) { |
2105 case GrGLRenderTarget::kCantResolve_ResolveType: | 2172 case GrGLRenderTarget::kCantResolve_ResolveType: |
2106 return false; | 2173 return false; |
2107 case GrGLRenderTarget::kAutoResolves_ResolveType: | 2174 case GrGLRenderTarget::kAutoResolves_ResolveType: |
2108 this->flushRenderTarget(tgt, &SkIRect::EmptyIRect()); | 2175 this->flushRenderTarget(renderTarget, &SkIRect::EmptyIRect()); |
2109 break; | 2176 break; |
2110 case GrGLRenderTarget::kCanResolve_ResolveType: | 2177 case GrGLRenderTarget::kCanResolve_ResolveType: |
2111 this->onResolveRenderTarget(tgt); | 2178 this->onResolveRenderTarget(renderTarget); |
2112 // we don't track the state of the READ FBO ID. | 2179 // we don't track the state of the READ FBO ID. |
2113 fStats.incRenderTargetBinds(); | 2180 fStats.incRenderTargetBinds(); |
2114 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, tgt->textureFBOID())
); | 2181 GL_CALL(BindFramebuffer(GR_GL_READ_FRAMEBUFFER, renderTarget->textur
eFBOID())); |
2115 break; | 2182 break; |
2116 default: | 2183 default: |
2117 SkFAIL("Unknown resolve type"); | 2184 SkFAIL("Unknown resolve type"); |
2118 } | 2185 } |
2119 | 2186 |
2120 const GrGLIRect& glvp = tgt->getViewport(); | 2187 const GrGLIRect& glvp = renderTarget->getViewport(); |
2121 | 2188 |
2122 // the read rect is viewport-relative | 2189 // the read rect is viewport-relative |
2123 GrGLIRect readRect; | 2190 GrGLIRect readRect; |
2124 readRect.setRelativeTo(glvp, left, top, width, height, tgt->origin()); | 2191 readRect.setRelativeTo(glvp, left, top, width, height, renderTarget->origin(
)); |
2125 | 2192 |
2126 size_t tightRowBytes = GrBytesPerPixel(config) * width; | 2193 size_t tightRowBytes = GrBytesPerPixel(config) * width; |
2127 | 2194 |
2128 size_t readDstRowBytes = tightRowBytes; | 2195 size_t readDstRowBytes = tightRowBytes; |
2129 void* readDst = buffer; | 2196 void* readDst = buffer; |
2130 | 2197 |
2131 // determine if GL can read using the passed rowBytes or if we need | 2198 // determine if GL can read using the passed rowBytes or if we need |
2132 // a scratch buffer. | 2199 // a scratch buffer. |
2133 SkAutoSMalloc<32 * sizeof(GrColor)> scratch; | 2200 SkAutoSMalloc<32 * sizeof(GrColor)> scratch; |
2134 if (rowBytes != tightRowBytes) { | 2201 if (rowBytes != tightRowBytes) { |
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3556 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 3623 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
3557 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 3624 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
3558 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 3625 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
3559 copyParams->fWidth = texture->width(); | 3626 copyParams->fWidth = texture->width(); |
3560 copyParams->fHeight = texture->height(); | 3627 copyParams->fHeight = texture->height(); |
3561 return true; | 3628 return true; |
3562 } | 3629 } |
3563 } | 3630 } |
3564 return false; | 3631 return false; |
3565 } | 3632 } |
OLD | NEW |