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

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

Issue 1264003002: SRGB read and write pixels working and unit test (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 4 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/SRGBReadWritePixelsTest.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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 fHWStencilTestEnabled = kUnknown_TriState; 348 fHWStencilTestEnabled = kUnknown_TriState;
349 } 349 }
350 350
351 // Vertex 351 // Vertex
352 if (resetBits & kVertex_GrGLBackendState) { 352 if (resetBits & kVertex_GrGLBackendState) {
353 fHWGeometryState.invalidate(); 353 fHWGeometryState.invalidate();
354 } 354 }
355 355
356 if (resetBits & kRenderTarget_GrGLBackendState) { 356 if (resetBits & kRenderTarget_GrGLBackendState) {
357 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; 357 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID;
358 fHWSRGBFramebuffer = kUnknown_TriState;
358 } 359 }
359 360
360 if (resetBits & kPathRendering_GrGLBackendState) { 361 if (resetBits & kPathRendering_GrGLBackendState) {
361 if (this->caps()->shaderCaps()->pathRenderingSupport()) { 362 if (this->caps()->shaderCaps()->pathRenderingSupport()) {
362 this->glPathRendering()->resetContext(); 363 this->glPathRendering()->resetContext();
363 } 364 }
364 } 365 }
365 366
366 // we assume these values 367 // we assume these values
367 if (resetBits & kPixelStore_GrGLBackendState) { 368 if (resetBits & kPixelStore_GrGLBackendState) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) { 513 if (kIndex_8_GrPixelConfig == srcConfig || GrPixelConfigIsCompressed(dstSurf ace->config())) {
513 return false; 514 return false;
514 } 515 }
515 516
516 // This subclass only allows writes to textures. If the dst is not a texture we have to draw 517 // This subclass only allows writes to textures. If the dst is not a texture we have to draw
517 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y. 518 // into it. We could use glDrawPixels on GLs that have it, but we don't toda y.
518 if (!dstSurface->asTexture()) { 519 if (!dstSurface->asTexture()) {
519 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 520 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
520 } 521 }
521 522
523 if (GrPixelConfigIsSRGB(dstSurface->config()) != GrPixelConfigIsSRGB(srcConf ig)) {
524 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
525 }
526
522 tempDrawInfo->fSwapRAndB = false; 527 tempDrawInfo->fSwapRAndB = false;
523 528
524 // These settings we will always want if a temp draw is performed. Initially set the config 529 // These settings we will always want if a temp draw is performed. Initially set the config
525 // to srcConfig, though that may be modified if we decide to do a R/G swap. 530 // to srcConfig, though that may be modified if we decide to do a R/G swap.
526 tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags; 531 tempDrawInfo->fTempSurfaceDesc.fFlags = kNone_GrSurfaceFlags;
527 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig; 532 tempDrawInfo->fTempSurfaceDesc.fConfig = srcConfig;
528 tempDrawInfo->fTempSurfaceDesc.fWidth = width; 533 tempDrawInfo->fTempSurfaceDesc.fWidth = width;
529 tempDrawInfo->fTempSurfaceDesc.fHeight = height; 534 tempDrawInfo->fTempSurfaceDesc.fHeight = height;
530 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 535 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
531 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 536 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
(...skipping 27 matching lines...) Expand all
559 return true; 564 return true;
560 } 565 }
561 566
562 bool GrGLGpu::onWritePixels(GrSurface* surface, 567 bool GrGLGpu::onWritePixels(GrSurface* surface,
563 int left, int top, int width, int height, 568 int left, int top, int width, int height,
564 GrPixelConfig config, const void* buffer, 569 GrPixelConfig config, const void* buffer,
565 size_t rowBytes) { 570 size_t rowBytes) {
566 if (NULL == buffer) { 571 if (NULL == buffer) {
567 return false; 572 return false;
568 } 573 }
574
569 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture()); 575 GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
570 if (!glTex) { 576 if (!glTex) {
571 return false; 577 return false;
572 } 578 }
573 579
580 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
581 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
582 return false;
583 }
584
574 this->setScratchTextureUnit(); 585 this->setScratchTextureUnit();
575 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); 586 GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
576 587
577 bool success = false; 588 bool success = false;
578 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) { 589 if (GrPixelConfigIsCompressed(glTex->desc().fConfig)) {
579 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s() 590 // We check that config == desc.fConfig in GrGLGpu::canWriteTexturePixel s()
580 SkASSERT(config == glTex->desc().fConfig); 591 SkASSERT(config == glTex->desc().fConfig);
581 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le ft, top, width, 592 success = this->uploadCompressedTexData(glTex->desc(), buffer, false, le ft, top, width,
582 height); 593 height);
583 } else { 594 } else {
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 1741
1731 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes, 1742 bool GrGLGpu::onGetReadPixelsInfo(GrSurface* srcSurface, int width, int height, size_t rowBytes,
1732 GrPixelConfig readConfig, DrawPreference* draw Preference, 1743 GrPixelConfig readConfig, DrawPreference* draw Preference,
1733 ReadPixelTempDrawInfo* tempDrawInfo) { 1744 ReadPixelTempDrawInfo* tempDrawInfo) {
1734 // This subclass can only read pixels from a render target. We could use glT exSubImage2D on 1745 // This subclass can only read pixels from a render target. We could use glT exSubImage2D on
1735 // GL versions that support it but we don't today. 1746 // GL versions that support it but we don't today.
1736 if (!srcSurface->asRenderTarget()) { 1747 if (!srcSurface->asRenderTarget()) {
1737 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference); 1748 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
1738 } 1749 }
1739 1750
1751 if (GrPixelConfigIsSRGB(srcSurface->config()) != GrPixelConfigIsSRGB(readCon fig)) {
1752 ElevateDrawPreference(drawPreference, kRequireDraw_DrawPreference);
1753 }
1754
1740 tempDrawInfo->fSwapRAndB = false; 1755 tempDrawInfo->fSwapRAndB = false;
1741 1756
1742 // These settings we will always want if a temp draw is performed. The confi g is set below 1757 // These settings we will always want if a temp draw is performed. The confi g is set below
1743 // depending on whether we want to do a R/B swap or not. 1758 // depending on whether we want to do a R/B swap or not.
1744 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag; 1759 tempDrawInfo->fTempSurfaceDesc.fFlags = kRenderTarget_GrSurfaceFlag;
1745 tempDrawInfo->fTempSurfaceDesc.fWidth = width; 1760 tempDrawInfo->fTempSurfaceDesc.fWidth = width;
1746 tempDrawInfo->fTempSurfaceDesc.fHeight = height; 1761 tempDrawInfo->fTempSurfaceDesc.fHeight = height;
1747 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0; 1762 tempDrawInfo->fTempSurfaceDesc.fSampleCnt = 0;
1748 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL. 1763 tempDrawInfo->fTempSurfaceDesc.fOrigin = kTopLeft_GrSurfaceOrigin; // no CPU y-flip for TL.
1749 tempDrawInfo->fUseExactScratch = SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_ PARTIAL) && 1764 tempDrawInfo->fUseExactScratch = SkToBool(GR_GL_FULL_READPIXELS_FASTER_THAN_ PARTIAL) &&
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 GrPixelConfig config, 1805 GrPixelConfig config,
1791 void* buffer, 1806 void* buffer,
1792 size_t rowBytes) { 1807 size_t rowBytes) {
1793 SkASSERT(surface); 1808 SkASSERT(surface);
1794 1809
1795 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(surface->asRenderTarg et()); 1810 GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(surface->asRenderTarg et());
1796 if (!tgt) { 1811 if (!tgt) {
1797 return false; 1812 return false;
1798 } 1813 }
1799 1814
1815 // OpenGL doesn't do sRGB <-> linear conversions when reading and writing pi xels.
1816 if (GrPixelConfigIsSRGB(surface->config()) != GrPixelConfigIsSRGB(config)) {
1817 return false;
1818 }
1819
1800 GrGLenum format = 0; 1820 GrGLenum format = 0;
1801 GrGLenum type = 0; 1821 GrGLenum type = 0;
1802 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin(); 1822 bool flipY = kBottomLeft_GrSurfaceOrigin == surface->origin();
1803 if (!this->configToGLFormats(config, false, NULL, &format, &type)) { 1823 if (!this->configToGLFormats(config, false, NULL, &format, &type)) {
1804 return false; 1824 return false;
1805 } 1825 }
1806 1826
1827 // glReadPixels does not allow GL_SRGB_ALPHA. Instead use GL_RGBA. This will not trigger a
1828 // conversion when the src is srgb.
1829 if (GR_GL_SRGB_ALPHA == format) {
1830 format = GR_GL_RGBA;
1831 }
1832
1807 // resolve the render target if necessary 1833 // resolve the render target if necessary
1808 switch (tgt->getResolveType()) { 1834 switch (tgt->getResolveType()) {
1809 case GrGLRenderTarget::kCantResolve_ResolveType: 1835 case GrGLRenderTarget::kCantResolve_ResolveType:
1810 return false; 1836 return false;
1811 case GrGLRenderTarget::kAutoResolves_ResolveType: 1837 case GrGLRenderTarget::kAutoResolves_ResolveType:
1812 this->flushRenderTarget(tgt, &SkIRect::EmptyIRect()); 1838 this->flushRenderTarget(tgt, &SkIRect::EmptyIRect());
1813 break; 1839 break;
1814 case GrGLRenderTarget::kCanResolve_ResolveType: 1840 case GrGLRenderTarget::kCanResolve_ResolveType:
1815 this->onResolveRenderTarget(tgt); 1841 this->onResolveRenderTarget(tgt);
1816 // we don't track the state of the READ FBO ID. 1842 // we don't track the state of the READ FBO ID.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1924 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x \n", status); 1950 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x \n", status);
1925 } 1951 }
1926 } 1952 }
1927 #endif 1953 #endif
1928 fHWBoundRenderTargetUniqueID = rtID; 1954 fHWBoundRenderTargetUniqueID = rtID;
1929 const GrGLIRect& vp = target->getViewport(); 1955 const GrGLIRect& vp = target->getViewport();
1930 if (fHWViewport != vp) { 1956 if (fHWViewport != vp) {
1931 vp.pushToGLViewport(this->glInterface()); 1957 vp.pushToGLViewport(this->glInterface());
1932 fHWViewport = vp; 1958 fHWViewport = vp;
1933 } 1959 }
1960 if (this->glCaps().srgbWriteControl()) {
1961 bool enableSRGBWrite = GrPixelConfigIsSRGB(target->config());
1962 if (enableSRGBWrite && kYes_TriState != fHWSRGBFramebuffer) {
1963 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB));
1964 fHWSRGBFramebuffer = kYes_TriState;
1965 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) {
1966 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB));
1967 fHWSRGBFramebuffer = kNo_TriState;
1968 }
1969 }
1934 } 1970 }
1935 if (NULL == bound || !bound->isEmpty()) { 1971 if (NULL == bound || !bound->isEmpty()) {
1936 target->flagAsNeedingResolve(bound); 1972 target->flagAsNeedingResolve(bound);
1937 } 1973 }
1938 1974
1939 GrTexture *texture = target->asTexture(); 1975 GrTexture *texture = target->asTexture();
1940 if (texture) { 1976 if (texture) {
1941 texture->texturePriv().dirtyMipMaps(true); 1977 texture->texturePriv().dirtyMipMaps(true);
1942 } 1978 }
1943 } 1979 }
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2430 if (getSizedInternalFormat) { 2466 if (getSizedInternalFormat) {
2431 *internalFormat = GR_GL_RGBA8; 2467 *internalFormat = GR_GL_RGBA8;
2432 } else { 2468 } else {
2433 *internalFormat = GR_GL_RGBA; 2469 *internalFormat = GR_GL_RGBA;
2434 } 2470 }
2435 } 2471 }
2436 *externalFormat = GR_GL_BGRA; 2472 *externalFormat = GR_GL_BGRA;
2437 *externalType = GR_GL_UNSIGNED_BYTE; 2473 *externalType = GR_GL_UNSIGNED_BYTE;
2438 break; 2474 break;
2439 case kSRGBA_8888_GrPixelConfig: 2475 case kSRGBA_8888_GrPixelConfig:
2440 *internalFormat = GR_GL_SRGB_ALPHA; 2476 if (getSizedInternalFormat) {
2441 *externalFormat = GR_GL_SRGB_ALPHA;
2442 if (getSizedInternalFormat || kGL_GrGLStandard == this->glStandard() ) {
2443 // desktop or ES 3.0
2444 SkASSERT(this->glVersion() >= GR_GL_VER(3, 0));
2445 *internalFormat = GR_GL_SRGB8_ALPHA8; 2477 *internalFormat = GR_GL_SRGB8_ALPHA8;
2478 } else {
2479 *internalFormat = GR_GL_SRGB_ALPHA;
2480 }
2481 // OpenGL ES 2.0 + GL_EXT_sRGB allows GL_SRGB_ALPHA to be specified as the <format>
2482 // param to Tex(Sub)Image2D. ES 2.0 requires the internalFormat and format to match.
2483 // Thus, on ES 2.0 we will use GL_SRGB_ALPHA as the externalFormat. However,
2484 // onReadPixels needs code to override that because GL_SRGB_ALPHA is not allowed as a
2485 // glReadPixels format.
2486 // On OpenGL and ES 3.0 GL_SRGB_ALPHA does not work for the <format> param to
2487 // glReadPixels nor does it work with Tex(Sub)Image2D So we always s et the externalFormat
2488 // return to GL_RGBA.
2489 if (this->glStandard() == kGLES_GrGLStandard &&
2490 this->glVersion() == GR_GL_VER(2,0)) {
2491 *externalFormat = GR_GL_SRGB_ALPHA;
2492 } else {
2446 *externalFormat = GR_GL_RGBA; 2493 *externalFormat = GR_GL_RGBA;
2447 } else {
2448 // ES 2.0 with EXT_sRGB
2449 SkASSERT(kGL_GrGLStandard != this->glStandard() &&
2450 this->glVersion() < GR_GL_VER(3, 0));
2451 *internalFormat = GR_GL_SRGB_ALPHA;
2452 *externalFormat = GR_GL_SRGB_ALPHA;
2453 } 2494 }
2454 *externalType = GR_GL_UNSIGNED_BYTE; 2495 *externalType = GR_GL_UNSIGNED_BYTE;
2455 break; 2496 break;
2456 case kRGB_565_GrPixelConfig: 2497 case kRGB_565_GrPixelConfig:
2457 *internalFormat = GR_GL_RGB; 2498 *internalFormat = GR_GL_RGB;
2458 *externalFormat = GR_GL_RGB; 2499 *externalFormat = GR_GL_RGB;
2459 if (getSizedInternalFormat) { 2500 if (getSizedInternalFormat) {
2460 if (!this->glCaps().ES2CompatibilitySupport()) { 2501 if (!this->glCaps().ES2CompatibilitySupport()) {
2461 *internalFormat = GR_GL_RGB5; 2502 *internalFormat = GR_GL_RGB5;
2462 } else { 2503 } else {
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
3169 this->setVertexArrayID(gpu, 0); 3210 this->setVertexArrayID(gpu, 0);
3170 } 3211 }
3171 int attrCount = gpu->glCaps().maxVertexAttributes(); 3212 int attrCount = gpu->glCaps().maxVertexAttributes();
3172 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3213 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3173 fDefaultVertexArrayAttribState.resize(attrCount); 3214 fDefaultVertexArrayAttribState.resize(attrCount);
3174 } 3215 }
3175 attribState = &fDefaultVertexArrayAttribState; 3216 attribState = &fDefaultVertexArrayAttribState;
3176 } 3217 }
3177 return attribState; 3218 return attribState;
3178 } 3219 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | tests/SRGBReadWritePixelsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698