Index: src/gpu/gl/GrGLGpu.cpp |
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp |
index c4ab4a2e2a6ef19b6d48f327f04a662b7e49a284..d5e53e92c70a5ba5cc55ba0c11b87e63368948be 100644 |
--- a/src/gpu/gl/GrGLGpu.cpp |
+++ b/src/gpu/gl/GrGLGpu.cpp |
@@ -1964,14 +1964,44 @@ static bool read_pixels_pays_for_y_flip(GrRenderTarget* renderTarget, const GrGL |
} |
bool GrGLGpu::readPixelsSupported(GrRenderTarget* target, GrPixelConfig readConfig) { |
- auto bindRenderTarget = [this](GrGLRenderTarget* target) { |
- this->flushRenderTarget(target, &SkIRect::EmptyIRect()); |
+ auto bindRenderTarget = [this, target]() -> bool { |
+ this->flushRenderTarget(static_cast<GrGLRenderTarget*>(target), &SkIRect::EmptyIRect()); |
+ return true; |
+ }; |
+ auto getIntegerv = [this](GrGLenum query, GrGLint* value) { |
+ GR_GL_GetIntegerv(this->glInterface(), query, value); |
+ }; |
+ GrPixelConfig rtConfig = target->config(); |
+ return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget); |
+} |
+ |
+bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConfig) { |
+ auto bindRenderTarget = [this, rtConfig]() -> bool { |
+ GrTextureDesc desc; |
+ desc.fConfig = rtConfig; |
+ desc.fWidth = desc.fHeight = 16; |
+ desc.fFlags = kRenderTarget_GrSurfaceFlag; |
+ SkAutoTUnref<GrTexture> temp(this->createTexture(desc, false, nullptr, 0)); |
+ if (!temp) { |
+ return false; |
+ } |
+ GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTarget()); |
+ this->flushRenderTarget(glrt, &SkIRect::EmptyIRect()); |
+ return true; |
}; |
auto getIntegerv = [this](GrGLenum query, GrGLint* value) { |
GR_GL_GetIntegerv(this->glInterface(), query, value); |
}; |
- GrGLRenderTarget* glTarget = static_cast<GrGLRenderTarget*>(target); |
- return this->glCaps().readPixelsSupported(glTarget, readConfig, getIntegerv, bindRenderTarget); |
+ return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv, bindRenderTarget); |
+} |
+ |
+bool GrGLGpu::readPixelsSupported(GrSurface* surfaceForConfig, GrPixelConfig readConfig) { |
+ if (GrRenderTarget* rt = surfaceForConfig->asRenderTarget()) { |
+ return this->readPixelsSupported(rt, readConfig); |
+ } else { |
+ GrPixelConfig config = surfaceForConfig->config(); |
+ return this->readPixelsSupported(config, readConfig); |
+ } |
} |
bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, |
@@ -2006,26 +2036,34 @@ bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, |
GrPixelConfig srcConfig = srcSurface->config(); |
tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig; |
- if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig) { |
+ if (this->glCaps().rgba8888PixelsOpsAreSlow() && kRGBA_8888_GrPixelConfig == readConfig && |
+ 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 (kMesa_GrGLDriver == this->glContext().driver() && |
GrBytesPerPixel(readConfig) == 4 && |
- GrPixelConfigSwapRAndB(readConfig) == srcConfig) { |
+ GrPixelConfigSwapRAndB(readConfig) == 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. |
tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; |
tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
tempDrawInfo->fReadConfig = srcConfig; |
ElevateDrawPreference(drawPreference, kGpuPrefersDraw_DrawPreference); |
- } else if (readConfig == kBGRA_8888_GrPixelConfig && |
- !this->readPixelsSupported(srcAsRT, readConfig)) { |
- tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; |
- tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
- tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; |
- ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
+ } else if (!this->readPixelsSupported(srcSurface, readConfig)) { |
+ if (readConfig == kBGRA_8888_GrPixelConfig && |
+ this->glCaps().isConfigRenderable(kRGBA_8888_GrPixelConfig, false) && |
+ this->readPixelsSupported(kRGBA_8888_GrPixelConfig, kRGBA_8888_GrPixelConfig)) { |
+ |
+ tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig; |
+ tempDrawInfo->fSwizzle = GrSwizzle::BGRA(); |
+ tempDrawInfo->fReadConfig = kRGBA_8888_GrPixelConfig; |
+ ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); |
+ } else { |
+ return false; |
+ } |
} |
if (srcAsRT && |