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 |