Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: src/gpu/SkGpuDevice.cpp

Issue 433553002: Add CTM to the cached layers' key and reduce render target pingponging in layer pre-rendering (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix yet another bug Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrLayerCache.cpp ('k') | tests/GpuLayerCacheTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 1864
1865 fContext->getLayerCache()->trackPicture(picture); 1865 fContext->getLayerCache()->trackPicture(picture);
1866 } 1866 }
1867 1867
1868 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re sult) { 1868 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re sult) {
1869 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 1869 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
1870 result->setInfo(info); 1870 result->setInfo(info);
1871 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); 1871 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
1872 } 1872 }
1873 1873
1874 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi cture) { 1874 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture * picture) {
1875 fContext->getLayerCache()->processDeletedPictures(); 1875 fContext->getLayerCache()->processDeletedPictures();
1876 1876
1877 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); 1877 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
1878 1878
1879 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); 1879 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key);
1880 if (NULL == data) { 1880 if (NULL == data) {
1881 return false; 1881 return false;
1882 } 1882 }
1883 1883
1884 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); 1884 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data);
1885 1885
1886 if (0 == gpuData->numSaveLayers()) { 1886 if (0 == gpuData->numSaveLayers()) {
1887 return false; 1887 return false;
1888 } 1888 }
1889 1889
1890 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); 1890 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers());
1891 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { 1891 for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
1892 pullForward[i] = false; 1892 pullForward[i] = false;
1893 } 1893 }
1894 1894
1895 SkRect clipBounds; 1895 SkRect clipBounds;
1896 if (!canvas->getClipBounds(&clipBounds)) { 1896 if (!mainCanvas->getClipBounds(&clipBounds)) {
1897 return true; 1897 return true;
1898 } 1898 }
1899 SkIRect query; 1899 SkIRect query;
1900 clipBounds.roundOut(&query); 1900 clipBounds.roundOut(&query);
1901 1901
1902 SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getA ctiveOps(query)); 1902 SkAutoTDelete<const SkPicture::OperationList> ops(picture->EXPERIMENTAL_getA ctiveOps(query));
1903 1903
1904 // This code pre-renders the entire layer since it will be cached and potent ially 1904 // This code pre-renders the entire layer since it will be cached and potent ially
1905 // reused with different clips (e.g., in different tiles). Because of this t he 1905 // reused with different clips (e.g., in different tiles). Because of this t he
1906 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM axSize 1906 // 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
1963 info.fIsNested) { 1963 info.fIsNested) {
1964 continue; 1964 continue;
1965 } 1965 }
1966 1966
1967 pullForward[j] = true; 1967 pullForward[j] = true;
1968 } 1968 }
1969 } 1969 }
1970 1970
1971 SkPictureReplacementPlayback::PlaybackReplacements replacements; 1971 SkPictureReplacementPlayback::PlaybackReplacements replacements;
1972 1972
1973 SkTDArray<GrCachedLayer*> atlased, nonAtlased;
1974 atlased.setReserve(gpuData->numSaveLayers());
1975
1973 // Generate the layer and/or ensure it is locked 1976 // Generate the layer and/or ensure it is locked
1974 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { 1977 for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
1975 if (pullForward[i]) { 1978 if (pullForward[i]) {
1976 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate( picture, i); 1979 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
1977 1980
1978 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); 1981 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate( picture,
1982 info.fSaveLayerOpID,
1983 info.fRestoreOpID,
1984 info.fCTM);
1979 1985
1980 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo = 1986 SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
1981 replacem ents.push(); 1987 replacem ents.push();
1982 layerInfo->fStart = info.fSaveLayerOpID; 1988 layerInfo->fStart = info.fSaveLayerOpID;
1983 layerInfo->fStop = info.fRestoreOpID; 1989 layerInfo->fStop = info.fRestoreOpID;
1984 layerInfo->fPos = info.fOffset; 1990 layerInfo->fPos = info.fOffset;
1985 1991
1986 GrTextureDesc desc; 1992 GrTextureDesc desc;
1987 desc.fFlags = kRenderTarget_GrTextureFlagBit; 1993 desc.fFlags = kRenderTarget_GrTextureFlagBit;
1988 desc.fWidth = info.fSize.fWidth; 1994 desc.fWidth = info.fSize.fWidth;
(...skipping 13 matching lines...) Expand all
2002 layerInfo->fBM); 2008 layerInfo->fBM);
2003 2009
2004 SkASSERT(info.fPaint); 2010 SkASSERT(info.fPaint);
2005 layerInfo->fPaint = info.fPaint; 2011 layerInfo->fPaint = info.fPaint;
2006 2012
2007 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft, 2013 layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft,
2008 layer->rect().fTop, 2014 layer->rect().fTop,
2009 layer->rect().width(), 2015 layer->rect().width(),
2010 layer->rect().height()); 2016 layer->rect().height());
2011 2017
2012
2013 if (needsRendering) { 2018 if (needsRendering) {
2014 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect (
2015 layer->texture()->asRenderTa rget(),
2016 SkSurface::kStandard_TextRen derMode,
2017 SkSurface::kDontClear_Render TargetFlag));
2018
2019 SkCanvas* canvas = surface->getCanvas();
2020
2021 // Add a rect clip to make sure the rendering doesn't
2022 // extend beyond the boundaries of the atlased sub-rect
2023 SkRect bound = SkRect::Make(layerInfo->fSrcRect);
2024 canvas->clipRect(bound);
2025
2026 if (layer->isAtlased()) { 2019 if (layer->isAtlased()) {
2027 // Since 'clear' doesn't respect the clip we need to draw a rect 2020 *atlased.append() = layer;
2028 // TODO: ensure none of the atlased layers contain a clear c all!
2029 SkPaint paint;
2030 paint.setColor(SK_ColorTRANSPARENT);
2031 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode)) ->unref();
2032 canvas->drawRect(bound, paint);
2033 } else { 2021 } else {
2034 canvas->clear(SK_ColorTRANSPARENT); 2022 *nonAtlased.append() = layer;
2035 } 2023 }
2036
2037 // info.fCTM maps the layer's top/left to the origin.
2038 // If this layer is atlased the top/left corner needs
2039 // to be offset to some arbitrary location in the backing
2040 // texture.
2041 canvas->translate(bound.fLeft, bound.fTop);
2042 canvas->concat(info.fCTM);
2043
2044 SkPictureRangePlayback rangePlayback(picture,
2045 info.fSaveLayerOpID,
2046 info.fRestoreOpID);
2047 rangePlayback.draw(canvas, NULL);
2048
2049 canvas->flush();
2050 } 2024 }
2051 } 2025 }
2052 } 2026 }
2053 2027
2054 // Playback using new layers 2028 // Render the atlased layers that require it
2029 if (atlased.count() > 0) {
2030 // All the atlased layers are rendered into the same GrTexture
2031 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
2032 atlased[0]->texture()->asRenderTarget(),
2033 SkSurface::kStandard_TextRenderMode,
2034 SkSurface::kDontClear_RenderTargetFlag)) ;
2035
2036 SkCanvas* atlasCanvas = surface->getCanvas();
2037
2038 SkPaint paint;
2039 paint.setColor(SK_ColorTRANSPARENT);
2040 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref();
2041
2042 for (int i = 0; i < atlased.count(); ++i) {
2043 GrCachedLayer* layer = atlased[i];
2044
2045 atlasCanvas->save();
2046
2047 // Add a rect clip to make sure the rendering doesn't
2048 // extend beyond the boundaries of the atlased sub-rect
2049 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
2050 SkIntToScalar(layer->rect().fTop),
2051 SkIntToScalar(layer->rect().width()) ,
2052 SkIntToScalar(layer->rect().height() ));
2053 atlasCanvas->clipRect(bound);
2054
2055 // Since 'clear' doesn't respect the clip we need to draw a rect
2056 // TODO: ensure none of the atlased layers contain a clear call!
2057 atlasCanvas->drawRect(bound, paint);
2058
2059 // info.fCTM maps the layer's top/left to the origin.
2060 // Since this layer is atlased, the top/left corner needs
2061 // to be offset to the correct location in the backing texture.
2062 atlasCanvas->translate(bound.fLeft, bound.fTop);
2063 atlasCanvas->concat(layer->ctm());
2064
2065 SkPictureRangePlayback rangePlayback(picture,
2066 layer->start(),
2067 layer->stop());
2068 rangePlayback.draw(atlasCanvas, NULL);
2069
2070 atlasCanvas->restore();
2071 }
2072
2073 atlasCanvas->flush();
2074 }
2075
2076 // Render the non-atlased layers that require it
2077 for (int i = 0; i < nonAtlased.count(); ++i) {
2078 GrCachedLayer* layer = nonAtlased[i];
2079
2080 // Each non-atlased layer has its own GrTexture
2081 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
2082 layer->texture()->asRenderTarget(),
2083 SkSurface::kStandard_TextRenderMode,
2084 SkSurface::kDontClear_RenderTargetFlag)) ;
2085
2086 SkCanvas* layerCanvas = surface->getCanvas();
2087
2088 // Add a rect clip to make sure the rendering doesn't
2089 // extend beyond the boundaries of the atlased sub-rect
2090 SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
2091 SkIntToScalar(layer->rect().fTop),
2092 SkIntToScalar(layer->rect().width()),
2093 SkIntToScalar(layer->rect().height()));
2094
2095 layerCanvas->clipRect(bound); // TODO: still useful?
2096
2097 layerCanvas->clear(SK_ColorTRANSPARENT);
2098
2099 layerCanvas->concat(layer->ctm());
2100
2101 SkPictureRangePlayback rangePlayback(picture,
2102 layer->start(),
2103 layer->stop());
2104 rangePlayback.draw(layerCanvas, NULL);
2105
2106 layerCanvas->flush();
2107 }
2108
2109 // Render the entire picture using new layers
2055 SkPictureReplacementPlayback playback(picture, &replacements, ops.get()); 2110 SkPictureReplacementPlayback playback(picture, &replacements, ops.get());
2056 2111
2057 playback.draw(canvas, NULL); 2112 playback.draw(mainCanvas, NULL);
2058 2113
2059 // unlock the layers 2114 // unlock the layers
2060 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { 2115 for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
2061 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture, i); 2116 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
2117
2118 GrCachedLayer* layer = fContext->getLayerCache()->findLayer(picture,
2119 info.fSaveLa yerOpID,
2120 info.fRestor eOpID,
2121 info.fCTM);
2062 fContext->getLayerCache()->unlock(layer); 2122 fContext->getLayerCache()->unlock(layer);
2063 } 2123 }
2064 2124
2065 return true; 2125 return true;
2066 } 2126 }
2067 2127
2068 SkImageFilter::UniqueIDCache* SkGpuDevice::getImageFilterCache() { 2128 SkImageFilter::UniqueIDCache* SkGpuDevice::getImageFilterCache() {
2069 // We always return a transient cache, so it is freed after each 2129 // We always return a transient cache, so it is freed after each
2070 // filter traversal. 2130 // filter traversal.
2071 return SkImageFilter::UniqueIDCache::Create(kDefaultImageFilterCacheSize); 2131 return SkImageFilter::UniqueIDCache::Create(kDefaultImageFilterCacheSize);
2072 } 2132 }
OLDNEW
« no previous file with comments | « src/gpu/GrLayerCache.cpp ('k') | tests/GpuLayerCacheTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698