| 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 |