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 10 matching lines...) Expand all Loading... |
21 | 21 |
22 #include "SkBounder.h" | 22 #include "SkBounder.h" |
23 #include "SkColorFilter.h" | 23 #include "SkColorFilter.h" |
24 #include "SkDeviceImageFilterProxy.h" | 24 #include "SkDeviceImageFilterProxy.h" |
25 #include "SkDrawProcs.h" | 25 #include "SkDrawProcs.h" |
26 #include "SkGlyphCache.h" | 26 #include "SkGlyphCache.h" |
27 #include "SkImageFilter.h" | 27 #include "SkImageFilter.h" |
28 #include "SkMaskFilter.h" | 28 #include "SkMaskFilter.h" |
29 #include "SkPathEffect.h" | 29 #include "SkPathEffect.h" |
30 #include "SkPicture.h" | 30 #include "SkPicture.h" |
| 31 #include "SkPicturePlayback.h" |
31 #include "SkRRect.h" | 32 #include "SkRRect.h" |
32 #include "SkStroke.h" | 33 #include "SkStroke.h" |
33 #include "SkSurface.h" | 34 #include "SkSurface.h" |
34 #include "SkTLazy.h" | 35 #include "SkTLazy.h" |
35 #include "SkUtils.h" | 36 #include "SkUtils.h" |
36 #include "SkErrorInternals.h" | 37 #include "SkErrorInternals.h" |
37 | 38 |
38 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 | 39 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 |
39 | 40 |
40 #if 0 | 41 #if 0 |
(...skipping 1872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1913 void SkGpuDevice::EXPERIMENTAL_optimize(SkPicture* picture) { | 1914 void SkGpuDevice::EXPERIMENTAL_optimize(SkPicture* picture) { |
1914 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); | 1915 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); |
1915 | 1916 |
1916 SkAutoTUnref<GPUAccelData> data(SkNEW_ARGS(GPUAccelData, (key))); | 1917 SkAutoTUnref<GPUAccelData> data(SkNEW_ARGS(GPUAccelData, (key))); |
1917 | 1918 |
1918 picture->EXPERIMENTAL_addAccelData(data); | 1919 picture->EXPERIMENTAL_addAccelData(data); |
1919 | 1920 |
1920 GatherGPUInfo(picture, data); | 1921 GatherGPUInfo(picture, data); |
1921 } | 1922 } |
1922 | 1923 |
| 1924 static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* re
sult) { |
| 1925 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
| 1926 result->setConfig(info); |
| 1927 result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); |
| 1928 } |
| 1929 |
1923 void SkGpuDevice::EXPERIMENTAL_purge(SkPicture* picture) { | 1930 void SkGpuDevice::EXPERIMENTAL_purge(SkPicture* picture) { |
1924 | 1931 |
1925 } | 1932 } |
1926 | 1933 |
1927 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, SkPicture* picture)
{ | 1934 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, SkPicture* picture)
{ |
1928 | 1935 |
1929 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); | 1936 SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey(); |
1930 | 1937 |
1931 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); | 1938 const SkPicture::AccelData* data = picture->EXPERIMENTAL_getAccelData(key); |
1932 if (NULL == data) { | 1939 if (NULL == data) { |
1933 return false; | 1940 return false; |
1934 } | 1941 } |
1935 | 1942 |
1936 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); | 1943 const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data); |
1937 | 1944 |
1938 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); | 1945 SkAutoTArray<bool> pullForward(gpuData->numSaveLayers()); |
1939 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { | 1946 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
1940 pullForward[i] = false; | 1947 pullForward[i] = false; |
1941 } | 1948 } |
1942 | 1949 |
1943 SkIRect clip; | 1950 SkRect clipBounds; |
| 1951 if (!canvas->getClipBounds(&clipBounds)) { |
| 1952 return true; |
| 1953 } |
| 1954 SkIRect query; |
| 1955 clipBounds.roundOut(&query); |
1944 | 1956 |
1945 fClipData.getConservativeBounds(this->width(), this->height(), &clip, NULL); | 1957 const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(que
ry); |
1946 | 1958 |
1947 SkMatrix inv; | 1959 // This code pre-renders the entire layer since it will be cached and potent
ially |
1948 if (!fContext->getMatrix().invert(&inv)) { | 1960 // reused with different clips (e.g., in different tiles). Because of this t
he |
1949 return false; | 1961 // clip will not be limiting the size of the pre-rendered layer. kSaveLayerM
axSize |
1950 } | 1962 // is used to limit which clips are pre-rendered. |
| 1963 static const int kSaveLayerMaxSize = 256; |
1951 | 1964 |
1952 SkRect r = SkRect::Make(clip); | 1965 if (ops.valid()) { |
1953 inv.mapRect(&r); | 1966 // In this case the picture has been generated with a BBH so we use |
1954 r.roundOut(&clip); | 1967 // the BBH to limit the pre-rendering to just the layers needed to cover
|
| 1968 // the region being drawn |
| 1969 for (int i = 0; i < ops.numOps(); ++i) { |
| 1970 uint32_t offset = ops.offset(i); |
1955 | 1971 |
1956 const SkPicture::OperationList& ops = picture->EXPERIMENTAL_getActiveOps(cli
p); | 1972 // For now we're saving all the layers in the GPUAccelData so they |
| 1973 // can be nested. Additionally, the nested layers appear before |
| 1974 // their parent in the list. |
| 1975 for (int j = 0 ; j < gpuData->numSaveLayers(); ++j) { |
| 1976 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo
(j); |
1957 | 1977 |
1958 for (int i = 0; i < ops.numOps(); ++i) { | 1978 if (pullForward[j]) { |
| 1979 continue; // already pulling forward |
| 1980 } |
| 1981 |
| 1982 if (offset < info.fSaveLayerOpID || offset > info.fRestoreOpID)
{ |
| 1983 continue; // the op isn't in this range |
| 1984 } |
| 1985 |
| 1986 // TODO: once this code is more stable unsuitable layers can |
| 1987 // just be omitted during the optimization stage |
| 1988 if (!info.fValid || |
| 1989 kSaveLayerMaxSize < info.fSize.fWidth || |
| 1990 kSaveLayerMaxSize < info.fSize.fHeight || |
| 1991 info.fIsNested) { |
| 1992 continue; // this layer is unsuitable |
| 1993 } |
| 1994 |
| 1995 pullForward[j] = true; |
| 1996 } |
| 1997 } |
| 1998 } else { |
| 1999 // In this case there is no BBH associated with the picture. Pre-render |
| 2000 // all the layers |
| 2001 // TODO: intersect the bounds of each layer with the clip region to |
| 2002 // reduce the number of pre-rendered layers |
1959 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { | 2003 for (int j = 0; j < gpuData->numSaveLayers(); ++j) { |
1960 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); | 2004 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(j); |
1961 | 2005 |
1962 if (ops.offset(i) > info.fSaveLayerOpID && ops.offset(i) < info.fRes
toreOpID) { | 2006 // TODO: once this code is more stable unsuitable layers can |
1963 pullForward[j] = true; | 2007 // just be omitted during the optimization stage |
| 2008 if (!info.fValid || |
| 2009 kSaveLayerMaxSize < info.fSize.fWidth || |
| 2010 kSaveLayerMaxSize < info.fSize.fHeight || |
| 2011 info.fIsNested) { |
| 2012 continue; |
| 2013 } |
| 2014 |
| 2015 pullForward[j] = true; |
| 2016 } |
| 2017 } |
| 2018 |
| 2019 SkPicturePlayback::PlaybackReplacements replacements; |
| 2020 |
| 2021 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
| 2022 if (pullForward[i]) { |
| 2023 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(
picture, i); |
| 2024 |
| 2025 const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i); |
| 2026 |
| 2027 if (NULL != picture->fPlayback) { |
| 2028 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerI
nfo = |
| 2029 replacem
ents.push(); |
| 2030 layerInfo->fStart = info.fSaveLayerOpID; |
| 2031 layerInfo->fStop = info.fRestoreOpID; |
| 2032 layerInfo->fPos = info.fOffset; |
| 2033 |
| 2034 GrTextureDesc desc; |
| 2035 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 2036 desc.fWidth = info.fSize.fWidth; |
| 2037 desc.fHeight = info.fSize.fHeight; |
| 2038 desc.fConfig = kSkia8888_GrPixelConfig; |
| 2039 // TODO: need to deal with sample count |
| 2040 |
| 2041 bool bNeedsRendering = true; |
| 2042 |
| 2043 // This just uses scratch textures and doesn't cache the texture
. |
| 2044 // This can yield a lot of re-rendering |
| 2045 if (NULL == layer->getTexture()) { |
| 2046 layer->setTexture(fContext->lockAndRefScratchTexture(desc, |
| 2047 GrContext::kApprox_Scrat
chTexMatch)); |
| 2048 if (NULL == layer->getTexture()) { |
| 2049 continue; |
| 2050 } |
| 2051 } else { |
| 2052 bNeedsRendering = false; |
| 2053 } |
| 2054 |
| 2055 layerInfo->fBM = SkNEW(SkBitmap); |
| 2056 wrap_texture(layer->getTexture(), desc.fWidth, desc.fHeight, lay
erInfo->fBM); |
| 2057 |
| 2058 SkASSERT(info.fPaint); |
| 2059 layerInfo->fPaint = info.fPaint; |
| 2060 |
| 2061 if (bNeedsRendering) { |
| 2062 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDi
rect( |
| 2063 layer->getTexture()->asR
enderTarget())); |
| 2064 |
| 2065 SkCanvas* canvas = surface->getCanvas(); |
| 2066 |
| 2067 canvas->setMatrix(info.fCTM); |
| 2068 canvas->clear(SK_ColorTRANSPARENT); |
| 2069 |
| 2070 picture->fPlayback->setDrawLimits(info.fSaveLayerOpID, info.
fRestoreOpID); |
| 2071 picture->fPlayback->draw(*canvas, NULL); |
| 2072 picture->fPlayback->setDrawLimits(0, 0); |
| 2073 canvas->flush(); |
| 2074 } |
1964 } | 2075 } |
1965 } | 2076 } |
1966 } | 2077 } |
1967 | 2078 |
1968 return false; | 2079 // Playback using new layers |
| 2080 picture->fPlayback->setReplacements(&replacements); |
| 2081 picture->fPlayback->draw(*canvas, NULL); |
| 2082 picture->fPlayback->setReplacements(NULL); |
| 2083 |
| 2084 for (int i = 0; i < gpuData->numSaveLayers(); ++i) { |
| 2085 GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(pict
ure, i); |
| 2086 |
| 2087 if (NULL != layer->getTexture()) { |
| 2088 fContext->unlockScratchTexture(layer->getTexture()); |
| 2089 layer->setTexture(NULL); |
| 2090 } |
| 2091 } |
| 2092 |
| 2093 return true; |
1969 } | 2094 } |
OLD | NEW |