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 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 | 1860 |
1861 fContext->getLayerCache()->trackPicture(picture); | 1861 fContext->getLayerCache()->trackPicture(picture); |
1862 } | 1862 } |
1863 | 1863 |
1864 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { | 1864 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
1865 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | 1865 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
1866 result->setInfo(info); | 1866 result->setInfo(info); |
1867 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); | 1867 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
1868 } | 1868 } |
1869 | 1869 |
1870 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi
cture) { | 1870 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
* picture) { |
1871 fContext->getLayerCache()->processDeletedPictures(); | 1871 fContext->getLayerCache()->processDeletedPictures(); |
1872 | 1872 |
1873 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); | 1873 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); |
1874 | 1874 |
1875 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); | 1875 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); |
1876 if (NULL == data) { | 1876 if (NULL == data) { |
1877 return false; | 1877 return false; |
1878 } | 1878 } |
1879 | 1879 |
1880 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); | 1880 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); |
1881 | 1881 |
1882 if (0 == gpuData->numSaveLayers()) { | 1882 if (0 == gpuData->numSaveLayers()) { |
1883 return false; | 1883 return false; |
1884 } | 1884 } |
1885 | 1885 |
1886 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); | 1886 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); |
1887 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 1887 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
1888 pullForward[i] = false; | 1888 pullForward[i] = false; |
1889 } | 1889 } |
1890 | 1890 |
1891 SkRect clipBounds; | 1891 SkRect clipBounds; |
1892 if (!canvas->getClipBounds(&clipBounds)) { | 1892 if (!mainCanvas->getClipBounds(&clipBounds)) { |
1893 return true; | 1893 return true; |
1894 } | 1894 } |
1895 SkIRect query; | 1895 SkIRect query; |
1896 clipBounds.roundOut(&query); | 1896 clipBounds.roundOut(&query); |
1897 | 1897 |
1898 SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getA
ctiveOps(query)); | 1898 SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getA
ctiveOps(query)); |
1899 | 1899 |
1900 // This code pre-renders the entire layer since it will be cached and potent
ially | 1900 // This code pre-renders the entire layer since it will be cached and potent
ially |
1901 // reused with different clips (e.g., in different tiles). Because of this t
he | 1901 // reused with different clips (e.g., in different tiles). Because of this t
he |
1902 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM
axSize | 1902 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM
axSize |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1959 info.fIsNested) { | 1959 info.fIsNested) { |
1960 continue; | 1960 continue; |
1961 } | 1961 } |
1962 | 1962 |
1963 pullForward[j] = true; | 1963 pullForward[j] = true; |
1964 } | 1964 } |
1965 } | 1965 } |
1966 | 1966 |
1967 SkPictureReplacementPlayback::PlaybackReplacements replacements; | 1967 SkPictureReplacementPlayback::PlaybackReplacements replacements; |
1968 | 1968 |
| 1969 SkTDArray<GrCachedLayer*> atlased, nonAtlased; |
| 1970 atlased.setReserve(gpuData->numSaveLayers()); |
| 1971 |
1969 // Generate the layer and/or ensure it is locked | 1972 // Generate the layer and/or ensure it is locked |
1970 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 1973 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
1971 if (pullForward[i]) { | 1974 if (pullForward[i]) { |
1972 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture, i); | 1975 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
1973 | 1976 |
1974 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); | 1977 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture, |
| 1978
info.fSaveLayerOpID, |
| 1979
info.fRestoreOpID, |
| 1980
info.fCTM); |
1975 | 1981 |
1976 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
layerInfo = | 1982 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
layerInfo = |
1977 replacem
ents.push(); | 1983 replacem
ents.push(); |
1978 layerInfo->fStart = info.fSaveLayerOpID; | 1984 layerInfo->fStart = info.fSaveLayerOpID; |
1979 layerInfo->fStop = info.fRestoreOpID; | 1985 layerInfo->fStop = info.fRestoreOpID; |
1980 layerInfo->fPos = info.fOffset; | 1986 layerInfo->fPos = info.fOffset; |
1981 | 1987 |
1982 GrTextureDesc desc; | 1988 GrTextureDesc desc; |
1983 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1989 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
1984 desc.fWidth = info.fSize.fWidth; | 1990 desc.fWidth = info.fSize.fWidth; |
(...skipping 13 matching lines...) Expand all Loading... |
1998 layerInfo->fBM); | 2004 layerInfo->fBM); |
1999 | 2005 |
2000 SkASSERT(info.fPaint); | 2006 SkASSERT(info.fPaint); |
2001 layerInfo->fPaint = info.fPaint; | 2007 layerInfo->fPaint = info.fPaint; |
2002 | 2008 |
2003 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, | 2009 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, |
2004 layer->rect().fTop, | 2010 layer->rect().fTop, |
2005 layer->rect().width(), | 2011 layer->rect().width(), |
2006 layer->rect().height()); | 2012 layer->rect().height()); |
2007 | 2013 |
2008 | |
2009 if (needsRendering) { | 2014 if (needsRendering) { |
2010 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect
( | |
2011 layer->texture()->asRenderTa
rget(), | |
2012 SkSurface::kStandard_TextRen
derMode, | |
2013 SkSurface::kDontClear_Render
TargetFlag)); | |
2014 | |
2015 SkCanvas* canvas = surface->getCanvas(); | |
2016 | |
2017 // Add a rect clip to make sure the rendering doesn't | |
2018 // extend beyond the boundaries of the atlased sub-rect | |
2019 SkRect bound = SkRect::Make(layerInfo->fSrcRect); | |
2020 canvas->clipRect(bound); | |
2021 | |
2022 if (layer->isAtlased()) { | 2015 if (layer->isAtlased()) { |
2023 // Since 'clear' doesn't respect the clip we need to draw a
rect | 2016 *atlased.append() = layer; |
2024 // TODO: ensure none of the atlased layers contain a clear c
all! | |
2025 SkPaint paint; | |
2026 paint.setColor(SK_ColorTRANSPARENT); | |
2027 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))
->unref(); | |
2028 canvas->drawRect(bound, paint); | |
2029 } else { | 2017 } else { |
2030 canvas->clear(SK_ColorTRANSPARENT); | 2018 *nonAtlased.append() = layer; |
2031 } | 2019 } |
2032 | |
2033 // info.fCTM maps the layer's top/left to the origin. | |
2034 // If this layer is atlased the top/left corner needs | |
2035 // to be offset to some arbitrary location in the backing | |
2036 // texture. | |
2037 canvas->translate(bound.fLeft, bound.fTop); | |
2038 canvas->concat(info.fCTM); | |
2039 | |
2040 SkPictureRangePlayback rangePlayback(picture, | |
2041 info.fSaveLayerOpID, | |
2042 info.fRestoreOpID); | |
2043 rangePlayback.draw(canvas, NULL); | |
2044 | |
2045 canvas->flush(); | |
2046 } | 2020 } |
2047 } | 2021 } |
2048 } | 2022 } |
2049 | 2023 |
2050 // Playback using new layers | 2024 // Render the atlased layers that require it |
| 2025 if (atlased.count() > 0) { |
| 2026 // All the atlased layers are rendered into the same GrTexture |
| 2027 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
| 2028 atlased[0]->texture()->asRenderTarget(), |
| 2029 SkSurface::kStandard_TextRenderMode, |
| 2030 SkSurface::kDontClear_RenderTargetFlag))
; |
| 2031 |
| 2032 SkCanvas* atlasCanvas = surface->getCanvas(); |
| 2033 |
| 2034 SkPaint paint; |
| 2035 paint.setColor(SK_ColorTRANSPARENT); |
| 2036 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref(); |
| 2037 |
| 2038 for (int i = 0; i < atlased.count(); ++i) { |
| 2039 GrCachedLayer* layer = atlased[i]; |
| 2040 |
| 2041 // Add a rect clip to make sure the rendering doesn't |
| 2042 // extend beyond the boundaries of the atlased sub-rect |
| 2043 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
| 2044 SkIntToScalar(layer->rect().fTop), |
| 2045 SkIntToScalar(layer->rect().width())
, |
| 2046 SkIntToScalar(layer->rect().height()
)); |
| 2047 atlasCanvas->clipRect(bound); |
| 2048 |
| 2049 // Since 'clear' doesn't respect the clip we need to draw a rect |
| 2050 // TODO: ensure none of the atlased layers contain a clear call! |
| 2051 atlasCanvas->drawRect(bound, paint); |
| 2052 |
| 2053 // info.fCTM maps the layer's top/left to the origin. |
| 2054 // Since this layer is atlased, the top/left corner needs |
| 2055 // to be offset to the correct location in the backing texture. |
| 2056 atlasCanvas->translate(bound.fLeft, bound.fTop); |
| 2057 atlasCanvas->concat(layer->ctm()); |
| 2058 |
| 2059 SkPictureRangePlayback rangePlayback(picture, |
| 2060 layer->start(), |
| 2061 layer->stop()); |
| 2062 rangePlayback.draw(atlasCanvas, NULL); |
| 2063 } |
| 2064 |
| 2065 atlasCanvas->flush(); |
| 2066 } |
| 2067 |
| 2068 // Render the non-atlased layers that require it |
| 2069 for (int i = 0; i < nonAtlased.count(); ++i) { |
| 2070 GrCachedLayer* layer = atlased[i]; |
| 2071 |
| 2072 // Each non-atlased layer has its own GrTexture |
| 2073 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect( |
| 2074 layer->texture()->asRenderTarget(), |
| 2075 SkSurface::kStandard_TextRenderMode, |
| 2076 SkSurface::kDontClear_RenderTargetFlag))
; |
| 2077 |
| 2078 SkCanvas* layerCanvas = surface->getCanvas(); |
| 2079 |
| 2080 // Add a rect clip to make sure the rendering doesn't |
| 2081 // extend beyond the boundaries of the atlased sub-rect |
| 2082 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft), |
| 2083 SkIntToScalar(layer->rect().fTop), |
| 2084 SkIntToScalar(layer->rect().width()), |
| 2085 SkIntToScalar(layer->rect().height())); |
| 2086 |
| 2087 layerCanvas->clipRect(bound); // TODO: still useful? |
| 2088 |
| 2089 layerCanvas->clear(SK_ColorTRANSPARENT); |
| 2090 |
| 2091 layerCanvas->concat(layer->ctm()); |
| 2092 |
| 2093 SkPictureRangePlayback rangePlayback(picture, |
| 2094 layer->start(), |
| 2095 layer->stop()); |
| 2096 rangePlayback.draw(layerCanvas, NULL); |
| 2097 |
| 2098 layerCanvas->flush(); |
| 2099 } |
| 2100 |
| 2101 // Render the entire picture using new layers |
2051 SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); | 2102 SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); |
2052 | 2103 |
2053 playback.draw(canvas, NULL); | 2104 playback.draw(mainCanvas, NULL); |
2054 | 2105 |
2055 // unlock the layers | 2106 // unlock the layers |
2056 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 2107 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
2057 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture, i); | 2108 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
| 2109 |
| 2110 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture, |
| 2111 info.fSaveLa
yerOpID, |
| 2112 info.fRestor
eOpID, |
| 2113 info.fCTM); |
2058 fContext->getLayerCache()->unlock(layer); | 2114 fContext->getLayerCache()->unlock(layer); |
2059 } | 2115 } |
2060 | 2116 |
2061 return true; | 2117 return true; |
2062 } | 2118 } |
OLD | NEW |