| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "GrContext.h" | 10 #include "GrContext.h" |
| 11 | 11 |
| 12 #include "effects/GrConvolutionEffect.h" | |
| 13 #include "effects/GrSingleTextureEffect.h" | 12 #include "effects/GrSingleTextureEffect.h" |
| 14 #include "effects/GrConfigConversionEffect.h" | 13 #include "effects/GrConfigConversionEffect.h" |
| 15 | 14 |
| 16 #include "GrBufferAllocPool.h" | 15 #include "GrBufferAllocPool.h" |
| 17 #include "GrGpu.h" | 16 #include "GrGpu.h" |
| 18 #include "GrDrawTargetCaps.h" | 17 #include "GrDrawTargetCaps.h" |
| 19 #include "GrIndexBuffer.h" | 18 #include "GrIndexBuffer.h" |
| 20 #include "GrInOrderDrawBuffer.h" | 19 #include "GrInOrderDrawBuffer.h" |
| 21 #include "GrOvalRenderer.h" | 20 #include "GrOvalRenderer.h" |
| 22 #include "GrPathRenderer.h" | 21 #include "GrPathRenderer.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 35 SK_DEFINE_INST_COUNT(GrDrawState) | 34 SK_DEFINE_INST_COUNT(GrDrawState) |
| 36 | 35 |
| 37 // It can be useful to set this to false to test whether a bug is caused by usin
g the | 36 // It can be useful to set this to false to test whether a bug is caused by usin
g the |
| 38 // InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffe
r, or to make | 37 // InOrderDrawBuffer, to compare performance of using/not using InOrderDrawBuffe
r, or to make |
| 39 // debugging simpler. | 38 // debugging simpler. |
| 40 SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, | 39 SK_CONF_DECLARE(bool, c_Defer, "gpu.deferContext", true, |
| 41 "Defers rendering in GrContext via GrInOrderDrawBuffer."); | 40 "Defers rendering in GrContext via GrInOrderDrawBuffer."); |
| 42 | 41 |
| 43 #define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) | 42 #define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw) |
| 44 | 43 |
| 45 #define MAX_BLUR_SIGMA 4.0f | |
| 46 | |
| 47 // When we're using coverage AA but the blend is incompatible (given gpu | 44 // When we're using coverage AA but the blend is incompatible (given gpu |
| 48 // limitations) should we disable AA or draw wrong? | 45 // limitations) should we disable AA or draw wrong? |
| 49 #define DISABLE_COVERAGE_AA_FOR_BLEND 1 | 46 #define DISABLE_COVERAGE_AA_FOR_BLEND 1 |
| 50 | 47 |
| 51 #if GR_DEBUG | 48 #if GR_DEBUG |
| 52 // change this to a 1 to see notifications when partial coverage fails | 49 // change this to a 1 to see notifications when partial coverage fails |
| 53 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 | 50 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 |
| 54 #else | 51 #else |
| 55 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 | 52 #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0 |
| 56 #endif | 53 #endif |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 GrSafeSetNull(fPathRendererChain); | 220 GrSafeSetNull(fPathRendererChain); |
| 224 GrSafeSetNull(fSoftwarePathRenderer); | 221 GrSafeSetNull(fSoftwarePathRenderer); |
| 225 } | 222 } |
| 226 | 223 |
| 227 size_t GrContext::getGpuTextureCacheBytes() const { | 224 size_t GrContext::getGpuTextureCacheBytes() const { |
| 228 return fTextureCache->getCachedResourceBytes(); | 225 return fTextureCache->getCachedResourceBytes(); |
| 229 } | 226 } |
| 230 | 227 |
| 231 //////////////////////////////////////////////////////////////////////////////// | 228 //////////////////////////////////////////////////////////////////////////////// |
| 232 | 229 |
| 233 namespace { | |
| 234 | |
| 235 void scale_rect(SkRect* rect, float xScale, float yScale) { | |
| 236 rect->fLeft = SkScalarMul(rect->fLeft, SkFloatToScalar(xScale)); | |
| 237 rect->fTop = SkScalarMul(rect->fTop, SkFloatToScalar(yScale)); | |
| 238 rect->fRight = SkScalarMul(rect->fRight, SkFloatToScalar(xScale)); | |
| 239 rect->fBottom = SkScalarMul(rect->fBottom, SkFloatToScalar(yScale)); | |
| 240 } | |
| 241 | |
| 242 float adjust_sigma(float sigma, int *scaleFactor, int *radius) { | |
| 243 *scaleFactor = 1; | |
| 244 while (sigma > MAX_BLUR_SIGMA) { | |
| 245 *scaleFactor *= 2; | |
| 246 sigma *= 0.5f; | |
| 247 } | |
| 248 *radius = static_cast<int>(ceilf(sigma * 3.0f)); | |
| 249 GrAssert(*radius <= GrConvolutionEffect::kMaxKernelRadius); | |
| 250 return sigma; | |
| 251 } | |
| 252 | |
| 253 void convolve_gaussian(GrDrawTarget* target, | |
| 254 GrTexture* texture, | |
| 255 const SkRect& rect, | |
| 256 float sigma, | |
| 257 int radius, | |
| 258 Gr1DKernelEffect::Direction direction) { | |
| 259 GrRenderTarget* rt = target->drawState()->getRenderTarget(); | |
| 260 GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit); | |
| 261 GrDrawState* drawState = target->drawState(); | |
| 262 drawState->setRenderTarget(rt); | |
| 263 SkAutoTUnref<GrEffectRef> conv(GrConvolutionEffect::CreateGaussian(texture, | |
| 264 direction
, | |
| 265 radius, | |
| 266 sigma)); | |
| 267 drawState->addColorEffect(conv); | |
| 268 target->drawSimpleRect(rect, NULL); | |
| 269 } | |
| 270 | |
| 271 } | |
| 272 | |
| 273 //////////////////////////////////////////////////////////////////////////////// | |
| 274 | |
| 275 GrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, | 230 GrTexture* GrContext::findAndRefTexture(const GrTextureDesc& desc, |
| 276 const GrCacheID& cacheID, | 231 const GrCacheID& cacheID, |
| 277 const GrTextureParams* params) { | 232 const GrTextureParams* params) { |
| 278 GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheI
D); | 233 GrResourceKey resourceKey = GrTexture::ComputeKey(fGpu, params, desc, cacheI
D); |
| 279 GrResource* resource = fTextureCache->find(resourceKey); | 234 GrResource* resource = fTextureCache->find(resourceKey); |
| 280 SkSafeRef(resource); | 235 SkSafeRef(resource); |
| 281 return static_cast<GrTexture*>(resource); | 236 return static_cast<GrTexture*>(resource); |
| 282 } | 237 } |
| 283 | 238 |
| 284 bool GrContext::isTextureInCache(const GrTextureDesc& desc, | 239 bool GrContext::isTextureInCache(const GrTextureDesc& desc, |
| (...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 } | 1672 } |
| 1718 GrConfigConversionEffect::PMConversion upmToPM = | 1673 GrConfigConversionEffect::PMConversion upmToPM = |
| 1719 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); | 1674 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); |
| 1720 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { | 1675 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { |
| 1721 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat
rix); | 1676 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat
rix); |
| 1722 } else { | 1677 } else { |
| 1723 return NULL; | 1678 return NULL; |
| 1724 } | 1679 } |
| 1725 } | 1680 } |
| 1726 | 1681 |
| 1727 GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, | |
| 1728 bool canClobberSrc, | |
| 1729 const SkRect& rect, | |
| 1730 float sigmaX, float sigmaY) { | |
| 1731 ASSERT_OWNED_RESOURCE(srcTexture); | |
| 1732 | |
| 1733 AutoRenderTarget art(this); | |
| 1734 | |
| 1735 AutoMatrix am; | |
| 1736 am.setIdentity(this); | |
| 1737 | |
| 1738 SkIRect clearRect; | |
| 1739 int scaleFactorX, radiusX; | |
| 1740 int scaleFactorY, radiusY; | |
| 1741 sigmaX = adjust_sigma(sigmaX, &scaleFactorX, &radiusX); | |
| 1742 sigmaY = adjust_sigma(sigmaY, &scaleFactorY, &radiusY); | |
| 1743 | |
| 1744 SkRect srcRect(rect); | |
| 1745 scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); | |
| 1746 srcRect.roundOut(); | |
| 1747 scale_rect(&srcRect, static_cast<float>(scaleFactorX), | |
| 1748 static_cast<float>(scaleFactorY)); | |
| 1749 | |
| 1750 AutoClip acs(this, srcRect); | |
| 1751 | |
| 1752 GrAssert(kBGRA_8888_GrPixelConfig == srcTexture->config() || | |
| 1753 kRGBA_8888_GrPixelConfig == srcTexture->config() || | |
| 1754 kAlpha_8_GrPixelConfig == srcTexture->config()); | |
| 1755 | |
| 1756 GrTextureDesc desc; | |
| 1757 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
| 1758 desc.fWidth = SkScalarFloorToInt(srcRect.width()); | |
| 1759 desc.fHeight = SkScalarFloorToInt(srcRect.height()); | |
| 1760 desc.fConfig = srcTexture->config(); | |
| 1761 | |
| 1762 GrAutoScratchTexture temp1, temp2; | |
| 1763 GrTexture* dstTexture = temp1.set(this, desc); | |
| 1764 GrTexture* tempTexture = canClobberSrc ? srcTexture : temp2.set(this, desc); | |
| 1765 if (NULL == dstTexture || NULL == tempTexture) { | |
| 1766 return NULL; | |
| 1767 } | |
| 1768 | |
| 1769 for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { | |
| 1770 GrPaint paint; | |
| 1771 SkMatrix matrix; | |
| 1772 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | |
| 1773 this->setRenderTarget(dstTexture->asRenderTarget()); | |
| 1774 SkRect dstRect(srcRect); | |
| 1775 scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, | |
| 1776 i < scaleFactorY ? 0.5f : 1.0f); | |
| 1777 GrTextureParams params(SkShader::kClamp_TileMode, true); | |
| 1778 paint.addColorTextureEffect(srcTexture, matrix, params); | |
| 1779 this->drawRectToRect(paint, dstRect, srcRect); | |
| 1780 srcRect = dstRect; | |
| 1781 srcTexture = dstTexture; | |
| 1782 SkTSwap(dstTexture, tempTexture); | |
| 1783 } | |
| 1784 | |
| 1785 SkIRect srcIRect; | |
| 1786 srcRect.roundOut(&srcIRect); | |
| 1787 | |
| 1788 if (sigmaX > 0.0f) { | |
| 1789 if (scaleFactorX > 1) { | |
| 1790 // Clear out a radius to the right of the srcRect to prevent the | |
| 1791 // X convolution from reading garbage. | |
| 1792 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | |
| 1793 radiusX, srcIRect.height()); | |
| 1794 this->clear(&clearRect, 0x0); | |
| 1795 } | |
| 1796 GrPaint paint; | |
| 1797 this->setRenderTarget(dstTexture->asRenderTarget()); | |
| 1798 AutoRestoreEffects are; | |
| 1799 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); | |
| 1800 convolve_gaussian(target, srcTexture, srcRect, sigmaX, radiusX, | |
| 1801 Gr1DKernelEffect::kX_Direction); | |
| 1802 srcTexture = dstTexture; | |
| 1803 SkTSwap(dstTexture, tempTexture); | |
| 1804 } | |
| 1805 | |
| 1806 if (sigmaY > 0.0f) { | |
| 1807 if (scaleFactorY > 1 || sigmaX > 0.0f) { | |
| 1808 // Clear out a radius below the srcRect to prevent the Y | |
| 1809 // convolution from reading garbage. | |
| 1810 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | |
| 1811 srcIRect.width(), radiusY); | |
| 1812 this->clear(&clearRect, 0x0); | |
| 1813 } | |
| 1814 | |
| 1815 this->setRenderTarget(dstTexture->asRenderTarget()); | |
| 1816 GrPaint paint; | |
| 1817 AutoRestoreEffects are; | |
| 1818 GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are); | |
| 1819 convolve_gaussian(target, srcTexture, srcRect, sigmaY, radiusY, | |
| 1820 Gr1DKernelEffect::kY_Direction); | |
| 1821 srcTexture = dstTexture; | |
| 1822 SkTSwap(dstTexture, tempTexture); | |
| 1823 } | |
| 1824 | |
| 1825 if (scaleFactorX > 1 || scaleFactorY > 1) { | |
| 1826 // Clear one pixel to the right and below, to accommodate bilinear | |
| 1827 // upsampling. | |
| 1828 clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, | |
| 1829 srcIRect.width() + 1, 1); | |
| 1830 this->clear(&clearRect, 0x0); | |
| 1831 clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, | |
| 1832 1, srcIRect.height()); | |
| 1833 this->clear(&clearRect, 0x0); | |
| 1834 SkMatrix matrix; | |
| 1835 matrix.setIDiv(srcTexture->width(), srcTexture->height()); | |
| 1836 this->setRenderTarget(dstTexture->asRenderTarget()); | |
| 1837 | |
| 1838 GrPaint paint; | |
| 1839 // FIXME: This should be mitchell, not bilinear. | |
| 1840 GrTextureParams params(SkShader::kClamp_TileMode, true); | |
| 1841 paint.addColorTextureEffect(srcTexture, matrix, params); | |
| 1842 | |
| 1843 SkRect dstRect(srcRect); | |
| 1844 scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); | |
| 1845 this->drawRectToRect(paint, dstRect, srcRect); | |
| 1846 srcRect = dstRect; | |
| 1847 srcTexture = dstTexture; | |
| 1848 SkTSwap(dstTexture, tempTexture); | |
| 1849 } | |
| 1850 if (srcTexture == temp1.texture()) { | |
| 1851 return temp1.detach(); | |
| 1852 } else if (srcTexture == temp2.texture()) { | |
| 1853 return temp2.detach(); | |
| 1854 } else { | |
| 1855 srcTexture->ref(); | |
| 1856 return srcTexture; | |
| 1857 } | |
| 1858 } | |
| 1859 | |
| 1860 /////////////////////////////////////////////////////////////////////////////// | 1682 /////////////////////////////////////////////////////////////////////////////// |
| 1861 #if GR_CACHE_STATS | 1683 #if GR_CACHE_STATS |
| 1862 void GrContext::printCacheStats() const { | 1684 void GrContext::printCacheStats() const { |
| 1863 fTextureCache->printStats(); | 1685 fTextureCache->printStats(); |
| 1864 } | 1686 } |
| 1865 #endif | 1687 #endif |
| OLD | NEW |