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

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

Issue 1255483005: Attempt to somewhat simplify GrContext::readSurfacePixels interaction with GrGpu. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments Created 5 years, 5 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
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | tests/ReadPixelsTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 fTempDstFBOID = 0; 260 fTempDstFBOID = 0;
261 fStencilClearFBOID = 0; 261 fStencilClearFBOID = 0;
262 fCopyProgram.fArrayBuffer = 0; 262 fCopyProgram.fArrayBuffer = 0;
263 fCopyProgram.fProgram = 0; 263 fCopyProgram.fProgram = 0;
264 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { 264 if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
265 this->glPathRendering()->abandonGpuResources(); 265 this->glPathRendering()->abandonGpuResources();
266 } 266 }
267 } 267 }
268 268
269 /////////////////////////////////////////////////////////////////////////////// 269 ///////////////////////////////////////////////////////////////////////////////
270 GrPixelConfig GrGLGpu::preferredReadPixelsConfig(GrPixelConfig readConfig,
271 GrPixelConfig surfaceConfig) co nst {
272 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) {
273 return kBGRA_8888_GrPixelConfig;
274 } else if (kMesa_GrGLDriver == this->glContext().driver() &&
275 GrBytesPerPixel(readConfig) == 4 &&
276 GrPixelConfigSwapRAndB(readConfig) == surfaceConfig) {
277 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA sur face and vice-versa.
278 // Perhaps this should be guarded by some compiletime or runtime check.
279 return surfaceConfig;
280 } else if (readConfig == kBGRA_8888_GrPixelConfig
281 && !this->glCaps().readPixelsSupported(
282 this->glInterface(),
283 GR_GL_BGRA,
284 GR_GL_UNSIGNED_BYTE,
285 surfaceConfig
286 )) {
287 return kRGBA_8888_GrPixelConfig;
288 } else {
289 return readConfig;
290 }
291 }
292 270
293 GrPixelConfig GrGLGpu::preferredWritePixelsConfig(GrPixelConfig writeConfig, 271 GrPixelConfig GrGLGpu::preferredWritePixelsConfig(GrPixelConfig writeConfig,
294 GrPixelConfig surfaceConfig) c onst { 272 GrPixelConfig surfaceConfig) c onst {
295 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfi g) { 273 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == writeConfi g) {
296 return kBGRA_8888_GrPixelConfig; 274 return kBGRA_8888_GrPixelConfig;
297 } else { 275 } else {
298 return writeConfig; 276 return writeConfig;
299 } 277 }
300 } 278 }
301 279
(...skipping 13 matching lines...) Expand all
315 kRGBA_8888_GrPixelConfig == texture->config()) { 293 kRGBA_8888_GrPixelConfig == texture->config()) {
316 return true; 294 return true;
317 } else { 295 } else {
318 return false; 296 return false;
319 } 297 }
320 } else { 298 } else {
321 return true; 299 return true;
322 } 300 }
323 } 301 }
324 302
325 bool GrGLGpu::fullReadPixelsIsFasterThanPartial() const {
326 return SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL);
327 }
328
329 void GrGLGpu::onResetContext(uint32_t resetBits) { 303 void GrGLGpu::onResetContext(uint32_t resetBits) {
330 // we don't use the zb at all 304 // we don't use the zb at all
331 if (resetBits & kMisc_GrGLBackendState) { 305 if (resetBits & kMisc_GrGLBackendState) {
332 GL_CALL(Disable(GR_GL_DEPTH_TEST)); 306 GL_CALL(Disable(GR_GL_DEPTH_TEST));
333 GL_CALL(DepthMask(GR_GL_FALSE)); 307 GL_CALL(DepthMask(GR_GL_FALSE));
334 308
335 fHWDrawFace = GrPipelineBuilder::kInvalid_DrawFace; 309 fHWDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
336 fHWDitherEnabled = kUnknown_TriState; 310 fHWDitherEnabled = kUnknown_TriState;
337 311
338 if (kGL_GrGLStandard == this->glStandard()) { 312 if (kGL_GrGLStandard == this->glStandard()) {
(...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 }; 1618 static const GrGLenum attachments[] = { GR_GL_COLOR_ATTACHMENT0 };
1645 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att achments), 1619 GL_CALL(DiscardFramebuffer(GR_GL_FRAMEBUFFER, SK_ARRAY_COUNT(att achments),
1646 attachments)); 1620 attachments));
1647 } 1621 }
1648 break; 1622 break;
1649 } 1623 }
1650 } 1624 }
1651 renderTarget->flagAsResolved(); 1625 renderTarget->flagAsResolved();
1652 } 1626 }
1653 1627
1654
1655 void GrGLGpu::clearStencil(GrRenderTarget* target) { 1628 void GrGLGpu::clearStencil(GrRenderTarget* target) {
1656 if (NULL == target) { 1629 if (NULL == target) {
1657 return; 1630 return;
1658 } 1631 }
1659 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); 1632 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
1660 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect()); 1633 this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
1661 1634
1662 this->disableScissor(); 1635 this->disableScissor();
1663 1636
1664 GL_CALL(StencilMask(0xffffffff)); 1637 GL_CALL(StencilMask(0xffffffff));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 GrScissorState scissorState; 1671 GrScissorState scissorState;
1699 scissorState.set(rect); 1672 scissorState.set(rect);
1700 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin()); 1673 this->flushScissor(scissorState, glRT->getViewport(), glRT->origin());
1701 1674
1702 GL_CALL(StencilMask((uint32_t) clipStencilMask)); 1675 GL_CALL(StencilMask((uint32_t) clipStencilMask));
1703 GL_CALL(ClearStencil(value)); 1676 GL_CALL(ClearStencil(value));
1704 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT)); 1677 GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
1705 fHWStencilSettings.invalidate(); 1678 fHWStencilSettings.invalidate();
1706 } 1679 }
1707 1680
1708 bool GrGLGpu::readPixelsWillPayForYFlip(GrRenderTarget* renderTarget, 1681 static bool read_pixels_pays_for_y_flip(GrRenderTarget* renderTarget, const GrGL Caps& caps,
1709 int left, int top, 1682 int width, int height, GrPixelConfig co nfig,
1710 int width, int height, 1683 size_t rowBytes) {
1711 GrPixelConfig config, 1684 // If this render target is already TopLeft, we don't need to flip.
1712 size_t rowBytes) const {
1713 // If this rendertarget is aready TopLeft, we don't need to flip.
1714 if (kTopLeft_GrSurfaceOrigin == renderTarget->origin()) { 1685 if (kTopLeft_GrSurfaceOrigin == renderTarget->origin()) {
1715 return false; 1686 return false;
1716 } 1687 }
1717 1688
1718 // if GL can do the flip then we'll never pay for it. 1689 // if GL can do the flip then we'll never pay for it.
1719 if (this->glCaps().packFlipYSupport()) { 1690 if (caps.packFlipYSupport()) {
1720 return false; 1691 return false;
1721 } 1692 }
1722 1693
1723 // If we have to do memcpy to handle non-trim rowBytes then we 1694 // If we have to do memcpy to handle non-trim rowBytes then we
1724 // get the flip for free. Otherwise it costs. 1695 // get the flip for free. Otherwise it costs.
1725 if (this->glCaps().packRowLengthSupport()) { 1696 // Note that we're assuming that 0 rowBytes has already been handled and tha t the width has been
1726 return true; 1697 // clipped.
1727 } 1698 return caps.packRowLengthSupport() || GrBytesPerPixel(config) * width == row Bytes;
1728 // If we have to do memcpys to handle rowBytes then y-flip is free 1699 }
1729 // Note the rowBytes might be tight to the passed in data, but if data 1700
1730 // gets clipped in x to the target the rowBytes will no longer be tight. 1701 void elevate_draw_preference(GrGpu::DrawPreference* preference, GrGpu::DrawPrefe rence elevation) {
1731 if (left >= 0 && (left + width) < renderTarget->width()) { 1702 GR_STATIC_ASSERT(GrGpu::kCallerPrefersDraw_DrawPreference > GrGpu::kNoDraw_D rawPreference);
1732 return 0 == rowBytes || 1703 GR_STATIC_ASSERT(GrGpu::kGpuPrefersDraw_DrawPreference >
1733 GrBytesPerPixel(config) * width == rowBytes; 1704 GrGpu::kCallerPrefersDraw_DrawPreference);
1734 } else { 1705 GR_STATIC_ASSERT(GrGpu::kRequireDraw_DrawPreference > GrGpu::kGpuPrefersDraw _DrawPreference);
1706 *preference = SkTMax(*preference, elevation);
1707 }
1708
1709 bool GrGLGpu::getReadPixelsInfo(GrSurface* srcSurface, int width, int height, si ze_t rowBytes,
1710 GrPixelConfig readConfig, DrawPreference* drawPr eference,
1711 ReadPixelTempDrawInfo* tempDrawInfo) {
1712 SkASSERT(drawPreference);
1713 SkASSERT(tempDrawInfo);
1714 SkASSERT(kGpuPrefersDraw_DrawPreference != *drawPreference);
1715
1716 if (GrPixelConfigIsCompressed(readConfig)) {
1735 return false; 1717 return false;
1736 } 1718 }
1719
1720 tempDrawInfo->fSwapRAndB = false;
1721
1722 // These settings we will always want if a temp draw is performed. The confi g is set below
1723 // depending on whether we want to do a R/B swap or not.
1724 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
1725 tempDrawInfo->fTempSurfaceDesc.fWidth = width;
1726 tempDrawInfo->fTempSurfaceDesc.fHeight = height;
1727 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
1728 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
1729 tempDrawInfo->fUseExactScratch = SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_ PARTIAL);
1730
1731 // Start off assuming that any temp draw should be to the readConfig, then c heck if that will
1732 // be inefficient.
1733 GrPixelConfig srcConfig = srcSurface->config();
1734 tempDrawInfo->fTempSurfaceDesc.fConfig = readConfig;
1735
1736 if (GR_GL_RGBA_8888_PIXEL_OPS_SLOW && kRGBA_8888_GrPixelConfig == readConfig ) {
1737 tempDrawInfo->fTempSurfaceDesc.fConfig = kBGRA_8888_GrPixelConfig;
1738 } else if (kMesa_GrGLDriver == this->glContext().driver() &&
1739 GrBytesPerPixel(readConfig) == 4 &&
1740 GrPixelConfigSwapRAndB(readConfig) == srcConfig) {
1741 // Mesa 3D takes a slow path on when reading back BGRA from an RGBA sur face and vice-versa.
1742 // Better to do a draw with a R/B swap and then read as the original con fig.
1743 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
1744 tempDrawInfo->fSwapRAndB = true;
1745 elevate_draw_preference(drawPreference, kGpuPrefersDraw_DrawPreference);
1746 } else if (readConfig == kBGRA_8888_GrPixelConfig &&
1747 !this->glCaps().readPixelsSupported(this->glInterface(), GR_GL_BG RA,
1748 GR_GL_UNSIGNED_BYTE, srcConfi g)) {
1749 tempDrawInfo->fTempSurfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
1750 tempDrawInfo->fSwapRAndB = true;
1751 elevate_draw_preference(drawPreference, kRequireDraw_DrawPreference);
1752 }
1753
1754 GrRenderTarget* srcAsRT = srcSurface->asRenderTarget();
1755 if (!srcAsRT) {
1756 elevate_draw_preference(drawPreference, kRequireDraw_DrawPreference);
1757 } else if (read_pixels_pays_for_y_flip(srcAsRT, this->glCaps(), width, heigh t, readConfig,
1758 rowBytes)) {
1759 elevate_draw_preference(drawPreference, kGpuPrefersDraw_DrawPreference);
1760 }
1761
1762 if (kRequireDraw_DrawPreference == *drawPreference && !srcSurface->asTexture ()) {
1763 return false;
1764 }
1765 return true;
1737 } 1766 }
1738 1767
1739 bool GrGLGpu::onReadPixels(GrRenderTarget* target, 1768 bool GrGLGpu::onReadPixels(GrRenderTarget* target,
1740 int left, int top, 1769 int left, int top,
1741 int width, int height, 1770 int width, int height,
1742 GrPixelConfig config, 1771 GrPixelConfig config,
1743 void* buffer, 1772 void* buffer,
1744 size_t rowBytes) { 1773 size_t rowBytes) {
1774 SkASSERT(target);
1775
1745 // We cannot read pixels into a compressed buffer 1776 // We cannot read pixels into a compressed buffer
1746 if (GrPixelConfigIsCompressed(config)) { 1777 if (GrPixelConfigIsCompressed(config)) {
1747 return false; 1778 return false;
1748 } 1779 }
1749 1780
1750 GrGLenum format = 0; 1781 GrGLenum format = 0;
1751 GrGLenum type = 0; 1782 GrGLenum type = 0;
1752 bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin(); 1783 bool flipY = kBottomLeft_GrSurfaceOrigin == target->origin();
1753 if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 1784 if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
1754 return false; 1785 return false;
(...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3129 this->setVertexArrayID(gpu, 0); 3160 this->setVertexArrayID(gpu, 0);
3130 } 3161 }
3131 int attrCount = gpu->glCaps().maxVertexAttributes(); 3162 int attrCount = gpu->glCaps().maxVertexAttributes();
3132 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3163 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3133 fDefaultVertexArrayAttribState.resize(attrCount); 3164 fDefaultVertexArrayAttribState.resize(attrCount);
3134 } 3165 }
3135 attribState = &fDefaultVertexArrayAttribState; 3166 attribState = &fDefaultVertexArrayAttribState;
3136 } 3167 }
3137 return attribState; 3168 return attribState;
3138 } 3169 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | tests/ReadPixelsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698