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

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

Issue 848903004: Require budget decision when creating a RenderTarget SkSurface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address initial comments Created 5 years, 11 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
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 30 matching lines...) Expand all
41 #include "SkTLazy.h" 41 #include "SkTLazy.h"
42 #include "SkUtils.h" 42 #include "SkUtils.h"
43 #include "SkVertState.h" 43 #include "SkVertState.h"
44 #include "SkXfermode.h" 44 #include "SkXfermode.h"
45 #include "SkErrorInternals.h" 45 #include "SkErrorInternals.h"
46 46
47 #if SK_SUPPORT_GPU 47 #if SK_SUPPORT_GPU
48 48
49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; 49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
50 50
51 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
52
53 #if 0 51 #if 0
54 extern bool (*gShouldDrawProc)(); 52 extern bool (*gShouldDrawProc)();
55 #define CHECK_SHOULD_DRAW(draw) \ 53 #define CHECK_SHOULD_DRAW(draw) \
56 do { \ 54 do { \
57 if (gShouldDrawProc && !gShouldDrawProc()) return; \ 55 if (gShouldDrawProc && !gShouldDrawProc()) return; \
58 this->prepareDraw(draw); \ 56 this->prepareDraw(draw); \
59 } while (0) 57 } while (0)
60 #else 58 #else
61 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw) 59 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
62 #endif 60 #endif
63 61
64 // This constant represents the screen alignment criterion in texels for 62 // This constant represents the screen alignment criterion in texels for
65 // requiring texture domain clamping to prevent color bleeding when drawing 63 // requiring texture domain clamping to prevent color bleeding when drawing
66 // a sub region of a larger source image. 64 // a sub region of a larger source image.
67 #define COLOR_BLEED_TOLERANCE 0.001f 65 #define COLOR_BLEED_TOLERANCE 0.001f
68 66
69 #define DO_DEFERRED_CLEAR() \ 67 #define DO_DEFERRED_CLEAR() \
70 do { \ 68 do { \
71 if (fFlags & kNeedClear_Flag) { \ 69 if (fNeedClear) { \
72 this->clearAll(); \ 70 this->clearAll(); \
73 } \ 71 } \
74 } while (false) \ 72 } while (false) \
75 73
76 /////////////////////////////////////////////////////////////////////////////// 74 ///////////////////////////////////////////////////////////////////////////////
77 75
78 #define CHECK_FOR_ANNOTATION(paint) \ 76 #define CHECK_FOR_ANNOTATION(paint) \
79 do { if (paint.getAnnotation()) { return; } } while (0) 77 do { if (paint.getAnnotation()) { return; } } while (0)
80 78
81 /////////////////////////////////////////////////////////////////////////////// 79 ///////////////////////////////////////////////////////////////////////////////
82 80
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 115
118 struct GrSkDrawProcs : public SkDrawProcs { 116 struct GrSkDrawProcs : public SkDrawProcs {
119 public: 117 public:
120 GrContext* fContext; 118 GrContext* fContext;
121 GrTextContext* fTextContext; 119 GrTextContext* fTextContext;
122 GrFontScaler* fFontScaler; // cached in the skia glyphcache 120 GrFontScaler* fFontScaler; // cached in the skia glyphcache
123 }; 121 };
124 122
125 /////////////////////////////////////////////////////////////////////////////// 123 ///////////////////////////////////////////////////////////////////////////////
126 124
127 SkGpuDevice* SkGpuDevice::Create(GrSurface* surface, const SkSurfaceProps& props , unsigned flags) { 125 SkGpuDevice* SkGpuDevice::Create(GrRenderTarget* rt, const SkSurfaceProps* props , unsigned flags) {
128 SkASSERT(surface); 126 if (!rt || rt->wasDestroyed()) {
129 if (NULL == surface->asRenderTarget() || surface->wasDestroyed()) {
130 return NULL; 127 return NULL;
131 } 128 }
132 return SkNEW_ARGS(SkGpuDevice, (surface, props, flags)); 129 return SkNEW_ARGS(SkGpuDevice, (rt, props, flags));
133 } 130 }
134 131
135 static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps& prop s) { 132 static SkDeviceProperties surfaceprops_to_deviceprops(const SkSurfaceProps* prop s) {
136 return SkDeviceProperties(props.pixelGeometry()); 133 if (props) {
134 return SkDeviceProperties(props->pixelGeometry());
135 } else {
136 return SkDeviceProperties(SkDeviceProperties::kLegacyLCD_InitType);
137 }
137 } 138 }
138 139
139 SkGpuDevice::SkGpuDevice(GrSurface* surface, const SkSurfaceProps& props, unsign ed flags) 140 static SkSurfaceProps copy_or_default_props(const SkSurfaceProps* props) {
141 if (props) {
142 return SkSurfaceProps(*props);
143 } else {
144 return SkSurfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
145 }
146 }
147
148 SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign ed flags)
140 : INHERITED(surfaceprops_to_deviceprops(props)) 149 : INHERITED(surfaceprops_to_deviceprops(props))
150 , fSurfaceProps(copy_or_default_props(props))
141 { 151 {
142 fDrawProcs = NULL; 152 fDrawProcs = NULL;
143 153
144 fContext = SkRef(surface->getContext()); 154 fContext = SkRef(rt->getContext());
155 fNeedClear = flags & kNeedClear_Flag;
145 156
146 fFlags = flags; 157 fRenderTarget = SkRef(rt);
147 158
148 fRenderTarget = SkRef(surface->asRenderTarget()); 159 SkImageInfo info = rt->surfacePriv().info();
149 160 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, rt));
150 SkImageInfo info = surface->surfacePriv().info();
151 SkPixelRef* pr = SkNEW_ARGS(SkGrPixelRef, (info, surface));
152 fLegacyBitmap.setInfo(info); 161 fLegacyBitmap.setInfo(info);
153 fLegacyBitmap.setPixelRef(pr)->unref(); 162 fLegacyBitmap.setPixelRef(pr)->unref();
154 163
155 bool useDFT = SkToBool(flags & kDFText_Flag); 164 bool useDFT = props && props->isUseDistanceFieldFonts();
156 fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProp erties(), useDFT); 165 fTextContext = this->context()->createTextContext(fRenderTarget, this->getLe akyProperties(),
166 useDFT);
157 } 167 }
158 168
159 SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo , 169 SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkSurface::Budgeted budgete d,
160 const SkSurfaceProps& props, int sampleCount) { 170 const SkImageInfo& origInfo, int sampleCount,
171 const SkSurfaceProps* props, unsigned flags) {
161 if (kUnknown_SkColorType == origInfo.colorType() || 172 if (kUnknown_SkColorType == origInfo.colorType() ||
162 origInfo.width() < 0 || origInfo.height() < 0) { 173 origInfo.width() < 0 || origInfo.height() < 0) {
163 return NULL; 174 return NULL;
164 } 175 }
165 176
177 if (!context) {
178 return NULL;
179 }
180
166 SkColorType ct = origInfo.colorType(); 181 SkColorType ct = origInfo.colorType();
167 SkAlphaType at = origInfo.alphaType(); 182 SkAlphaType at = origInfo.alphaType();
168 // TODO: perhaps we can loosen this check now that colortype is more detaile d
169 // e.g. can we support both RGBA and BGRA here?
170 if (kRGB_565_SkColorType == ct) { 183 if (kRGB_565_SkColorType == ct) {
171 at = kOpaque_SkAlphaType; // force this setting 184 at = kOpaque_SkAlphaType; // force this setting
172 } else { 185 } else if (ct != kBGRA_8888_SkColorType && ct != kRGBA_8888_SkColorType) {
186 // Fall back from whatever ct was to default of kRGBA or kBGRA which is aliased as kN32
173 ct = kN32_SkColorType; 187 ct = kN32_SkColorType;
174 if (kOpaque_SkAlphaType != at) { 188 }
175 at = kPremul_SkAlphaType; // force this setting 189 if (kOpaque_SkAlphaType != at) {
176 } 190 at = kPremul_SkAlphaType; // force this setting
177 } 191 }
178 const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height (), ct, at); 192 const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height (), ct, at);
179 193
180 GrSurfaceDesc desc; 194 GrSurfaceDesc desc;
181 desc.fFlags = kRenderTarget_GrSurfaceFlag; 195 desc.fFlags = kRenderTarget_GrSurfaceFlag;
182 desc.fWidth = info.width(); 196 desc.fWidth = info.width();
183 desc.fHeight = info.height(); 197 desc.fHeight = info.height();
184 desc.fConfig = SkImageInfo2GrPixelConfig(info); 198 desc.fConfig = SkImageInfo2GrPixelConfig(info);
185 desc.fSampleCnt = sampleCount; 199 desc.fSampleCnt = sampleCount;
186 200
187 SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0 )); 201 SkAutoTUnref<GrTexture> texture;
188 if (!texture.get()) { 202 if (SkSurface::kYes_Budgeted == budgeted) {
203 texture.reset(context->refScratchTexture(desc, GrContext::kExact_Scratch TexMatch));
204 } else {
205 texture.reset(context->createUncachedTexture(desc, NULL, 0));
206 }
207
208 if (!texture) {
189 return NULL; 209 return NULL;
190 } 210 }
191 211
192 return SkNEW_ARGS(SkGpuDevice, (texture.get(), props)); 212 return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags));
193 } 213 }
194 214
195 SkGpuDevice::~SkGpuDevice() { 215 SkGpuDevice::~SkGpuDevice() {
196 if (fDrawProcs) { 216 if (fDrawProcs) {
197 delete fDrawProcs; 217 delete fDrawProcs;
198 } 218 }
199 219
200 delete fTextContext; 220 delete fTextContext;
201 221
202 // The GrContext takes a ref on the target. We don't want to cause the rende r 222 // The GrContext takes a ref on the target. We don't want to cause the rende r
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 GrRenderTarget* SkGpuDevice::accessRenderTarget() { 308 GrRenderTarget* SkGpuDevice::accessRenderTarget() {
289 DO_DEFERRED_CLEAR(); 309 DO_DEFERRED_CLEAR();
290 return fRenderTarget; 310 return fRenderTarget;
291 } 311 }
292 312
293 void SkGpuDevice::clearAll() { 313 void SkGpuDevice::clearAll() {
294 GrColor color = 0; 314 GrColor color = 0;
295 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext); 315 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::clearAll", fContext);
296 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); 316 SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
297 fContext->clear(&rect, color, true, fRenderTarget); 317 fContext->clear(&rect, color, true, fRenderTarget);
298 fFlags &= ~kNeedClear_Flag; 318 fNeedClear = false;
299 } 319 }
300 320
301 /////////////////////////////////////////////////////////////////////////////// 321 ///////////////////////////////////////////////////////////////////////////////
302 322
303 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); 323 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
304 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); 324 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch);
305 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); 325 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch);
306 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); 326 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch);
307 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, 327 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
308 shader_type_mismatch); 328 shader_type_mismatch);
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 dstSize.fHeight = tmpDst.height(); 1530 dstSize.fHeight = tmpDst.height();
1511 1531
1512 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags); 1532 this->drawBitmapCommon(*draw, bitmap, &tmpSrc, &dstSize, paint, flags);
1513 } 1533 }
1514 1534
1515 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, 1535 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
1516 int x, int y, const SkPaint& paint) { 1536 int x, int y, const SkPaint& paint) {
1517 // clear of the source device must occur before CHECK_SHOULD_DRAW 1537 // clear of the source device must occur before CHECK_SHOULD_DRAW
1518 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); 1538 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
1519 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); 1539 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
1520 if (dev->fFlags & kNeedClear_Flag) { 1540 if (fNeedClear) {
1521 // TODO: could check here whether we really need to draw at all 1541 // TODO: could check here whether we really need to draw at all
1522 dev->clearAll(); 1542 dev->clearAll();
1523 } 1543 }
1524 1544
1525 // drawDevice is defined to be in device coords. 1545 // drawDevice is defined to be in device coords.
1526 CHECK_SHOULD_DRAW(draw); 1546 CHECK_SHOULD_DRAW(draw);
1527 1547
1528 GrRenderTarget* devRT = dev->accessRenderTarget(); 1548 GrRenderTarget* devRT = dev->accessRenderTarget();
1529 GrTexture* devTex; 1549 GrTexture* devTex;
1530 if (NULL == (devTex = devRT->asTexture())) { 1550 if (NULL == (devTex = devRT->asTexture())) {
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 GrSurfaceDesc desc; 1813 GrSurfaceDesc desc;
1794 desc.fConfig = fRenderTarget->config(); 1814 desc.fConfig = fRenderTarget->config();
1795 desc.fFlags = kRenderTarget_GrSurfaceFlag; 1815 desc.fFlags = kRenderTarget_GrSurfaceFlag;
1796 desc.fWidth = cinfo.fInfo.width(); 1816 desc.fWidth = cinfo.fInfo.width();
1797 desc.fHeight = cinfo.fInfo.height(); 1817 desc.fHeight = cinfo.fInfo.height();
1798 desc.fSampleCnt = fRenderTarget->numSamples(); 1818 desc.fSampleCnt = fRenderTarget->numSamples();
1799 1819
1800 SkAutoTUnref<GrTexture> texture; 1820 SkAutoTUnref<GrTexture> texture;
1801 // Skia's convention is to only clear a device if it is non-opaque. 1821 // Skia's convention is to only clear a device if it is non-opaque.
1802 unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag; 1822 unsigned flags = cinfo.fInfo.isOpaque() ? 0 : kNeedClear_Flag;
1803 // If we're using distance field text, enable in the new device
1804 flags |= (fFlags & kDFText_Flag) ? kDFText_Flag : 0;
1805 1823
1806 #if CACHE_COMPATIBLE_DEVICE_TEXTURES
1807 // layers are never draw in repeat modes, so we can request an approx 1824 // layers are never draw in repeat modes, so we can request an approx
1808 // match and ignore any padding. 1825 // match and ignore any padding.
1809 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage) ? 1826 const GrContext::ScratchTexMatch match = (kSaveLayer_Usage == cinfo.fUsage) ?
1810 GrContext::kApprox_ScratchTexMat ch : 1827 GrContext::kApprox_ScratchTexMat ch :
1811 GrContext::kExact_ScratchTexMatc h; 1828 GrContext::kExact_ScratchTexMatc h;
1812 texture.reset(fContext->refScratchTexture(desc, match)); 1829 texture.reset(fContext->refScratchTexture(desc, match));
1813 #else 1830
1814 texture.reset(fContext->createUncachedTexture(desc, NULL, 0)); 1831 if (texture) {
1815 #endif 1832 SkSurfaceProps props(fSurfaceProps.flags(), cinfo.fPixelGeometry);
1816 if (texture.get()) { 1833 return SkGpuDevice::Create(texture->asRenderTarget(), &props, flags);
1817 return SkGpuDevice::Create(texture, SkSurfaceProps(0, cinfo.fPixelGeomet ry), flags);
1818 } else { 1834 } else {
1819 SkDebugf("---- failed to create compatible device texture [%d %d]\n", 1835 SkDebugf("---- failed to create compatible device texture [%d %d]\n",
1820 cinfo.fInfo.width(), cinfo.fInfo.height()); 1836 cinfo.fInfo.width(), cinfo.fInfo.height());
1821 return NULL; 1837 return NULL;
1822 } 1838 }
1823 } 1839 }
1824 1840
1825 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps & props) { 1841 SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps & props) {
1826 return SkSurface::NewRenderTarget(fContext, info, fRenderTarget->numSamples( ), &props); 1842 // TODO: Change the signature of newSurface to take a budgeted parameter.
1843 static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
1844 return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget-> numSamples(),
1845 &props);
1827 } 1846 }
1828 1847
1829 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture * mainPicture, 1848 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture * mainPicture,
1830 const SkMatrix* matrix, const SkPaint * paint) { 1849 const SkMatrix* matrix, const SkPaint * paint) {
1831 #ifndef SK_IGNORE_GPU_LAYER_HOISTING 1850 #ifndef SK_IGNORE_GPU_LAYER_HOISTING
1832 // todo: should handle this natively 1851 // todo: should handle this natively
1833 if (paint) { 1852 if (paint) {
1834 return false; 1853 return false;
1835 } 1854 }
1836 1855
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1885 #endif 1904 #endif
1886 } 1905 }
1887 1906
1888 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1907 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
1889 // We always return a transient cache, so it is freed after each 1908 // We always return a transient cache, so it is freed after each
1890 // filter traversal. 1909 // filter traversal.
1891 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1910 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
1892 } 1911 }
1893 1912
1894 #endif 1913 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | src/image/SkImage_Gpu.cpp » ('j') | tests/SurfaceTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698