OLD | NEW |
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 #include "SkGpuDevice.h" | 8 #include "SkGpuDevice.h" |
9 | 9 |
10 #include "effects/GrBicubicEffect.h" | 10 #include "effects/GrBicubicEffect.h" |
(...skipping 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 | 1610 |
1611 void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, | 1611 void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, |
1612 int vertexCount, const SkPoint vertices[], | 1612 int vertexCount, const SkPoint vertices[], |
1613 const SkPoint texs[], const SkColor colors[], | 1613 const SkPoint texs[], const SkColor colors[], |
1614 SkXfermode* xmode, | 1614 SkXfermode* xmode, |
1615 const uint16_t indices[], int indexCount, | 1615 const uint16_t indices[], int indexCount, |
1616 const SkPaint& paint) { | 1616 const SkPaint& paint) { |
1617 CHECK_SHOULD_DRAW(draw, false); | 1617 CHECK_SHOULD_DRAW(draw, false); |
1618 | 1618 |
1619 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext); | 1619 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext); |
1620 | 1620 |
1621 const uint16_t* outIndices; | 1621 const uint16_t* outIndices; |
1622 SkAutoTDeleteArray<uint16_t> outAlloc(NULL); | 1622 SkAutoTDeleteArray<uint16_t> outAlloc(NULL); |
1623 GrPrimitiveType primType; | 1623 GrPrimitiveType primType; |
1624 GrPaint grPaint; | 1624 GrPaint grPaint; |
1625 | 1625 |
1626 // If both textures and vertex-colors are NULL, strokes hairlines with the p
aint's color. | 1626 // If both textures and vertex-colors are NULL, strokes hairlines with the p
aint's color. |
1627 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) { | 1627 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) { |
1628 | 1628 |
1629 texs = NULL; | 1629 texs = NULL; |
1630 | 1630 |
1631 SkPaint copy(paint); | 1631 SkPaint copy(paint); |
1632 copy.setStyle(SkPaint::kStroke_Style); | 1632 copy.setStyle(SkPaint::kStroke_Style); |
1633 copy.setStrokeWidth(0); | 1633 copy.setStrokeWidth(0); |
1634 | 1634 |
1635 // we ignore the shader if texs is null. | 1635 // we ignore the shader if texs is null. |
1636 SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getC
olor()), | 1636 SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getC
olor()), |
1637 NULL == colors, &grPaint); | 1637 NULL == colors, &grPaint); |
1638 | 1638 |
1639 primType = kLines_GrPrimitiveType; | 1639 primType = kLines_GrPrimitiveType; |
1640 int triangleCount = 0; | 1640 int triangleCount = 0; |
1641 int n = (NULL == indices) ? vertexCount : indexCount; | 1641 int n = (NULL == indices) ? vertexCount : indexCount; |
1642 switch (vmode) { | 1642 switch (vmode) { |
1643 case SkCanvas::kTriangles_VertexMode: | 1643 case SkCanvas::kTriangles_VertexMode: |
1644 triangleCount = n / 3; | 1644 triangleCount = n / 3; |
1645 break; | 1645 break; |
1646 case SkCanvas::kTriangleStrip_VertexMode: | 1646 case SkCanvas::kTriangleStrip_VertexMode: |
1647 case SkCanvas::kTriangleFan_VertexMode: | 1647 case SkCanvas::kTriangleFan_VertexMode: |
1648 triangleCount = n - 2; | 1648 triangleCount = n - 2; |
1649 break; | 1649 break; |
1650 } | 1650 } |
1651 | 1651 |
1652 VertState state(vertexCount, indices, indexCount); | 1652 VertState state(vertexCount, indices, indexCount); |
1653 VertState::Proc vertProc = state.chooseProc(vmode); | 1653 VertState::Proc vertProc = state.chooseProc(vmode); |
1654 | 1654 |
1655 //number of indices for lines per triangle with kLines | 1655 //number of indices for lines per triangle with kLines |
1656 indexCount = triangleCount * 6; | 1656 indexCount = triangleCount * 6; |
1657 | 1657 |
1658 outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount)); | 1658 outAlloc.reset(SkNEW_ARRAY(uint16_t, indexCount)); |
1659 outIndices = outAlloc.get(); | 1659 outIndices = outAlloc.get(); |
1660 uint16_t* auxIndices = outAlloc.get(); | 1660 uint16_t* auxIndices = outAlloc.get(); |
1661 int i = 0; | 1661 int i = 0; |
1662 while (vertProc(&state)) { | 1662 while (vertProc(&state)) { |
1663 auxIndices[i] = state.f0; | 1663 auxIndices[i] = state.f0; |
1664 auxIndices[i + 1] = state.f1; | 1664 auxIndices[i + 1] = state.f1; |
1665 auxIndices[i + 2] = state.f1; | 1665 auxIndices[i + 2] = state.f1; |
1666 auxIndices[i + 3] = state.f2; | 1666 auxIndices[i + 3] = state.f2; |
1667 auxIndices[i + 4] = state.f2; | 1667 auxIndices[i + 4] = state.f2; |
1668 auxIndices[i + 5] = state.f0; | 1668 auxIndices[i + 5] = state.f0; |
1669 i += 6; | 1669 i += 6; |
1670 } | 1670 } |
1671 } else { | 1671 } else { |
1672 outIndices = indices; | 1672 outIndices = indices; |
1673 primType = gVertexMode2PrimitiveType[vmode]; | 1673 primType = gVertexMode2PrimitiveType[vmode]; |
1674 | 1674 |
1675 if (NULL == texs || NULL == paint.getShader()) { | 1675 if (NULL == texs || NULL == paint.getShader()) { |
1676 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(pain
t.getColor()), | 1676 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(pain
t.getColor()), |
1677 NULL == colors, &grPaint); | 1677 NULL == colors, &grPaint); |
1678 } else { | 1678 } else { |
1679 SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPai
nt); | 1679 SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPai
nt); |
1680 } | 1680 } |
1681 } | 1681 } |
1682 | 1682 |
1683 #if 0 | 1683 #if 0 |
1684 if (NULL != xmode && NULL != texs && NULL != colors) { | 1684 if (NULL != xmode && NULL != texs && NULL != colors) { |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 | 1872 |
1873 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { | 1873 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
1874 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | 1874 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
1875 result->setInfo(info); | 1875 result->setInfo(info); |
1876 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); | 1876 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
1877 } | 1877 } |
1878 | 1878 |
1879 // Return true if any layers are suitable for hoisting | 1879 // Return true if any layers are suitable for hoisting |
1880 bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData, | 1880 bool SkGpuDevice::FindLayersToHoist(const GrAccelData *gpuData, |
1881 const SkPicture::OperationList* ops, | 1881 const SkPicture::OperationList* ops, |
1882 const SkIRect& query, | 1882 const SkRect& query, |
1883 bool* pullForward) { | 1883 bool* pullForward) { |
1884 bool anyHoisted = false; | 1884 bool anyHoisted = false; |
1885 | 1885 |
1886 // Layer hoisting pre-renders the entire layer since it will be cached and p
otentially | 1886 // Layer hoisting pre-renders the entire layer since it will be cached and p
otentially |
1887 // reused with different clips (e.g., in different tiles). Because of this t
he | 1887 // reused with different clips (e.g., in different tiles). Because of this t
he |
1888 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM
axSize | 1888 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM
axSize |
1889 // is used to limit which clips are pre-rendered. | 1889 // is used to limit which clips are pre-rendered. |
1890 static const int kSaveLayerMaxSize = 256; | 1890 static const int kSaveLayerMaxSize = 256; |
1891 | 1891 |
1892 if (NULL != ops) { | 1892 if (NULL != ops) { |
(...skipping 29 matching lines...) Expand all Loading... |
1922 pullForward[j] = true; | 1922 pullForward[j] = true; |
1923 anyHoisted = true; | 1923 anyHoisted = true; |
1924 } | 1924 } |
1925 } | 1925 } |
1926 } else { | 1926 } else { |
1927 // In this case there is no BBH associated with the picture. Pre-render | 1927 // In this case there is no BBH associated with the picture. Pre-render |
1928 // all the layers that intersect the drawn region | 1928 // all the layers that intersect the drawn region |
1929 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { | 1929 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { |
1930 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); | 1930 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); |
1931 | 1931 |
1932 SkIRect layerRect = SkIRect::MakeXYWH(info.fOffset.fX, | 1932 SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX), |
1933 info.fOffset.fY, | 1933 SkIntToScalar(info.fOffset.fY), |
1934 info.fSize.fWidth, | 1934 SkIntToScalar(info.fSize.fWidth)
, |
1935 info.fSize.fHeight); | 1935 SkIntToScalar(info.fSize.fHeight
)); |
1936 | 1936 |
1937 if (!SkIRect::Intersects(query, layerRect)) { | 1937 if (!SkRect::Intersects(query, layerRect)) { |
1938 continue; | 1938 continue; |
1939 } | 1939 } |
1940 | 1940 |
1941 // TODO: once this code is more stable unsuitable layers can | 1941 // TODO: once this code is more stable unsuitable layers can |
1942 // just be omitted during the optimization stage | 1942 // just be omitted during the optimization stage |
1943 if (!info.fValid || | 1943 if (!info.fValid || |
1944 kSaveLayerMaxSize < info.fSize.fWidth || | 1944 kSaveLayerMaxSize < info.fSize.fWidth || |
1945 kSaveLayerMaxSize < info.fSize.fHeight || | 1945 kSaveLayerMaxSize < info.fSize.fHeight || |
1946 info.fIsNested) { | 1946 info.fIsNested) { |
1947 continue; | 1947 continue; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1979 | 1979 |
1980 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); | 1980 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); |
1981 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 1981 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
1982 pullForward[i] = false; | 1982 pullForward[i] = false; |
1983 } | 1983 } |
1984 | 1984 |
1985 SkRect clipBounds; | 1985 SkRect clipBounds; |
1986 if (!mainCanvas->getClipBounds(&clipBounds)) { | 1986 if (!mainCanvas->getClipBounds(&clipBounds)) { |
1987 return true; | 1987 return true; |
1988 } | 1988 } |
1989 SkIRect query; | |
1990 clipBounds.roundOut(&query); | |
1991 | 1989 |
1992 SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getA
ctiveOps(query)); | 1990 SkAutoTDelete<const SkPicture::OperationList> ops( |
| 1991 picture->EXPERIMENTAL_getActiveOps(clipBounds)); |
1993 | 1992 |
1994 if (!FindLayersToHoist(gpuData, ops.get(), query, pullForward.get())) { | 1993 if (!FindLayersToHoist(gpuData, ops.get(), clipBounds, pullForward.get())) { |
1995 return false; | 1994 return false; |
1996 } | 1995 } |
1997 | 1996 |
1998 SkPictureReplacementPlayback::PlaybackReplacements replacements; | 1997 SkPictureReplacementPlayback::PlaybackReplacements replacements; |
1999 | 1998 |
2000 SkTDArray<GrCachedLayer*> atlased, nonAtlased; | 1999 SkTDArray<GrCachedLayer*> atlased, nonAtlased; |
2001 atlased.setReserve(gpuData->numSaveLayers()); | 2000 atlased.setReserve(gpuData->numSaveLayers()); |
2002 | 2001 |
2003 // Generate the layer and/or ensure it is locked | 2002 // Generate the layer and/or ensure it is locked |
2004 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 2003 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
2005 if (pullForward[i]) { | 2004 if (pullForward[i]) { |
2006 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); | 2005 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
2007 | 2006 |
2008 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture->uniqueID(), | 2007 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture->uniqueID(), |
2009
info.fSaveLayerOpID, | 2008
info.fSaveLayerOpID, |
2010
info.fRestoreOpID, | 2009
info.fRestoreOpID, |
2011
info.fCTM); | 2010
info.fCTM); |
2012 | 2011 |
2013 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
layerInfo = | 2012 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
layerInfo = |
2014 replacem
ents.push(); | 2013 replacem
ents.push(); |
2015 layerInfo->fStart = info.fSaveLayerOpID; | 2014 layerInfo->fStart = info.fSaveLayerOpID; |
2016 layerInfo->fStop = info.fRestoreOpID; | 2015 layerInfo->fStop = info.fRestoreOpID; |
2017 layerInfo->fPos = info.fOffset; | 2016 layerInfo->fPos = info.fOffset; |
2018 | 2017 |
2019 GrTextureDesc desc; | 2018 GrTextureDesc desc; |
2020 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 2019 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
2021 desc.fWidth = info.fSize.fWidth; | 2020 desc.fWidth = info.fSize.fWidth; |
2022 desc.fHeight = info.fSize.fHeight; | 2021 desc.fHeight = info.fSize.fHeight; |
2023 desc.fConfig = kSkia8888_GrPixelConfig; | 2022 desc.fConfig = kSkia8888_GrPixelConfig; |
2024 // TODO: need to deal with sample count | 2023 // TODO: need to deal with sample count |
2025 | 2024 |
2026 bool needsRendering = fContext->getLayerCache()->lock(layer, desc, | 2025 bool needsRendering = fContext->getLayerCache()->lock(layer, desc, |
2027 info.fHasNestedLayers || inf
o.fIsNested); | 2026 info.fHasNestedLayers || inf
o.fIsNested); |
2028 if (NULL == layer->texture()) { | 2027 if (NULL == layer->texture()) { |
2029 continue; | 2028 continue; |
2030 } | 2029 } |
2031 | 2030 |
2032 layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so Replacemen
tInfo can be POD | 2031 layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so Replacemen
tInfo can be POD |
2033 wrap_texture(layer->texture(), | 2032 wrap_texture(layer->texture(), |
2034 !layer->isAtlased() ? desc.fWidth : layer->texture()->w
idth(), | 2033 !layer->isAtlased() ? desc.fWidth : layer->texture()->w
idth(), |
2035 !layer->isAtlased() ? desc.fHeight : layer->texture()->
height(), | 2034 !layer->isAtlased() ? desc.fHeight : layer->texture()->
height(), |
2036 layerInfo->fBM); | 2035 layerInfo->fBM); |
2037 | 2036 |
2038 SkASSERT(info.fPaint); | 2037 SkASSERT(info.fPaint); |
2039 layerInfo->fPaint = info.fPaint; | 2038 layerInfo->fPaint = info.fPaint; |
2040 | 2039 |
2041 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, | 2040 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, |
2042 layer->rect().fTop, | 2041 layer->rect().fTop, |
2043 layer->rect().width(), | 2042 layer->rect().width(), |
(...skipping 15 matching lines...) Expand all Loading... |
2059 SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); | 2058 SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); |
2060 | 2059 |
2061 playback.draw(mainCanvas, NULL); | 2060 playback.draw(mainCanvas, NULL); |
2062 | 2061 |
2063 this->unlockLayers(picture); | 2062 this->unlockLayers(picture); |
2064 | 2063 |
2065 return true; | 2064 return true; |
2066 } | 2065 } |
2067 | 2066 |
2068 void SkGpuDevice::drawLayers(const SkPicture* picture, | 2067 void SkGpuDevice::drawLayers(const SkPicture* picture, |
2069 const SkTDArray<GrCachedLayer*>& atlased, | 2068 const SkTDArray<GrCachedLayer*>& atlased, |
2070 const SkTDArray<GrCachedLayer*>& nonAtlased) { | 2069 const SkTDArray<GrCachedLayer*>& nonAtlased) { |
2071 // Render the atlased layers that require it | 2070 // Render the atlased layers that require it |
2072 if (atlased.count() > 0) { | 2071 if (atlased.count() > 0) { |
2073 // All the atlased layers are rendered into the same GrTexture | 2072 // All the atlased layers are rendered into the same GrTexture |
2074 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( | 2073 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
2075 atlased[0]->texture()->asRenderTarge
t(), | 2074 atlased[0]->texture()->asRenderTarge
t(), |
2076 SkSurface::kStandard_TextRenderMode, | 2075 SkSurface::kStandard_TextRenderMode, |
2077 SkSurface::kDontClear_RenderTargetFl
ag)); | 2076 SkSurface::kDontClear_RenderTargetFl
ag)); |
2078 | 2077 |
2079 SkCanvas* atlasCanvas = surface->getCanvas(); | 2078 SkCanvas* atlasCanvas = surface->getCanvas(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2164 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); | 2163 const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
2165 | 2164 |
2166 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uni
queID(), | 2165 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture->uni
queID(), |
2167 info.fSaveLa
yerOpID, | 2166 info.fSaveLa
yerOpID, |
2168 info.fRestor
eOpID, | 2167 info.fRestor
eOpID, |
2169 info.fCTM); | 2168 info.fCTM); |
2170 fContext->getLayerCache()->unlock(layer); | 2169 fContext->getLayerCache()->unlock(layer); |
2171 } | 2170 } |
2172 | 2171 |
2173 #if DISABLE_CACHING | 2172 #if DISABLE_CACHING |
2174 // This code completely clears out the atlas. It is required when | 2173 // This code completely clears out the atlas. It is required when |
2175 // caching is disabled so the atlas doesn't fill up and force more | 2174 // caching is disabled so the atlas doesn't fill up and force more |
2176 // free floating layers | 2175 // free floating layers |
2177 fContext->getLayerCache()->purge(picture->uniqueID()); | 2176 fContext->getLayerCache()->purge(picture->uniqueID()); |
2178 | 2177 |
2179 fContext->getLayerCache()->purgeAll(); | 2178 fContext->getLayerCache()->purgeAll(); |
2180 #endif | 2179 #endif |
2181 } | 2180 } |
2182 | 2181 |
2183 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 2182 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
2184 // We always return a transient cache, so it is freed after each | 2183 // We always return a transient cache, so it is freed after each |
2185 // filter traversal. | 2184 // filter traversal. |
2186 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 2185 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
2187 } | 2186 } |
OLD | NEW |