1
2 /*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9 #include "GrTest.h"
10
11 #include "GrGpuResourceCacheAccess.h"
12 #include "GrInOrderDrawBuffer.h"
13 #include "GrResourceCache.h"
14 #include "SkString.h"
15
init(GrContext * ctx,GrDrawTarget * target)16 void GrTestTarget::init(GrContext* ctx, GrDrawTarget* target) {
17 SkASSERT(!fContext);
18
19 fContext.reset(SkRef(ctx));
20 fDrawTarget.reset(SkRef(target));
21 }
22
getTestTarget(GrTestTarget * tar)23 void GrContext::getTestTarget(GrTestTarget* tar) {
24 this->flush();
25 // We could create a proxy GrDrawTarget that passes through to fGpu until ~GrTextTarget() and
26 // then disconnects. This would help prevent test writers from mixing using the returned
27 // GrDrawTarget and regular drawing. We could also assert or fail in GrContext drawing methods
28 // until ~GrTestTarget().
29 tar->init(this, fDrawBuffer);
30 }
31
32 ///////////////////////////////////////////////////////////////////////////////
33
setMaxTextureSizeOverride(int maxTextureSizeOverride)34 void GrContext::setMaxTextureSizeOverride(int maxTextureSizeOverride) {
35 fMaxTextureSizeOverride = maxTextureSizeOverride;
36 }
37
purgeAllUnlockedResources()38 void GrContext::purgeAllUnlockedResources() {
39 fResourceCache->purgeAllUnlocked();
40 }
41
dumpCacheStats(SkString * out) const42 void GrContext::dumpCacheStats(SkString* out) const {
43 #if GR_CACHE_STATS
44 fResourceCache->dumpStats(out);
45 #endif
46 }
47
printCacheStats() const48 void GrContext::printCacheStats() const {
49 SkString out;
50 this->dumpCacheStats(&out);
51 SkDebugf("%s", out.c_str());
52 }
53
dumpGpuStats(SkString * out) const54 void GrContext::dumpGpuStats(SkString* out) const {
55 #if GR_GPU_STATS
56 return fGpu->stats()->dump(out);
57 #endif
58 }
59
printGpuStats() const60 void GrContext::printGpuStats() const {
61 SkString out;
62 this->dumpGpuStats(&out);
63 SkDebugf("%s", out.c_str());
64 }
65
66 #if GR_GPU_STATS
dump(SkString * out)67 void GrGpu::Stats::dump(SkString* out) {
68 out->appendf("Render Target Binds: %d\n", fRenderTargetBinds);
69 out->appendf("Shader Compilations: %d\n", fShaderCompilations);
70 out->appendf("Textures Created: %d\n", fTextureCreates);
71 out->appendf("Texture Uploads: %d\n", fTextureUploads);
72 out->appendf("Stencil Buffer Creates: %d\n", fStencilAttachmentCreates);
73 }
74 #endif
75
76 #if GR_CACHE_STATS
dumpStats(SkString * out) const77 void GrResourceCache::dumpStats(SkString* out) const {
78 this->validate();
79
80 int locked = fNonpurgeableResources.count();
81
82 struct Stats {
83 int fScratch;
84 int fWrapped;
85 size_t fUnbudgetedSize;
86
87 Stats() : fScratch(0), fWrapped(0), fUnbudgetedSize(0) {}
88
89 void update(GrGpuResource* resource) {
90 if (resource->cacheAccess().isScratch()) {
91 ++fScratch;
92 }
93 if (resource->cacheAccess().isWrapped()) {
94 ++fWrapped;
95 }
96 if (!resource->resourcePriv().isBudgeted()) {
97 fUnbudgetedSize += resource->gpuMemorySize();
98 }
99 }
100 };
101
102 Stats stats;
103
104 for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
105 stats.update(fNonpurgeableResources[i]);
106 }
107 for (int i = 0; i < fPurgeableQueue.count(); ++i) {
108 stats.update(fPurgeableQueue.at(i));
109 }
110
111 float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
112 float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;
113
114 out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
115 out->appendf("\t\tEntry Count: current %d"
116 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
117 this->getResourceCount(), fBudgetedCount, stats.fWrapped, locked, stats.fScratch,
118 countUtilization, fHighWaterCount);
119 out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
120 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
121 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
122 }
123
124 #endif
125
126 ///////////////////////////////////////////////////////////////////////////////
127
changeTimestamp(uint32_t newTimestamp)128 void GrResourceCache::changeTimestamp(uint32_t newTimestamp) { fTimestamp = newTimestamp; }
129
130 ///////////////////////////////////////////////////////////////////////////////
131 // Code for the mock context. It's built on a mock GrGpu class that does nothing.
132 ////
133
134 #include "GrInOrderDrawBuffer.h"
135 #include "GrGpu.h"
136
137 class GrPipeline;
138
139 class MockGpu : public GrGpu {
140 public:
MockGpu(GrContext * context)141 MockGpu(GrContext* context) : INHERITED(context) { fCaps.reset(SkNEW(GrDrawTargetCaps)); }
~MockGpu()142 ~MockGpu() override {}
canWriteTexturePixels(const GrTexture *,GrPixelConfig srcConfig) const143 bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override {
144 return true;
145 }
146
readPixelsWillPayForYFlip(GrRenderTarget * renderTarget,int left,int top,int width,int height,GrPixelConfig config,size_t rowBytes) const147 bool readPixelsWillPayForYFlip(GrRenderTarget* renderTarget,
148 int left, int top,
149 int width, int height,
150 GrPixelConfig config,
151 size_t rowBytes) const override { return false; }
buildProgramDesc(GrProgramDesc *,const GrPrimitiveProcessor &,const GrPipeline &,const GrBatchTracker &) const152 void buildProgramDesc(GrProgramDesc*,const GrPrimitiveProcessor&,
153 const GrPipeline&,
154 const GrBatchTracker&) const override {}
155
discard(GrRenderTarget *)156 void discard(GrRenderTarget*) override {}
157
canCopySurface(const GrSurface * dst,const GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)158 bool canCopySurface(const GrSurface* dst,
159 const GrSurface* src,
160 const SkIRect& srcRect,
161 const SkIPoint& dstPoint) override { return false; };
162
copySurface(GrSurface * dst,GrSurface * src,const SkIRect & srcRect,const SkIPoint & dstPoint)163 bool copySurface(GrSurface* dst,
164 GrSurface* src,
165 const SkIRect& srcRect,
166 const SkIPoint& dstPoint) override { return false; };
167
initCopySurfaceDstDesc(const GrSurface * src,GrSurfaceDesc * desc)168 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override {
169 return false;
170 }
171
xferBarrier(GrRenderTarget *,GrXferBarrierType)172 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
173
174 private:
onResetContext(uint32_t resetBits)175 void onResetContext(uint32_t resetBits) override {}
176
onCreateTexture(const GrSurfaceDesc & desc,GrGpuResource::LifeCycle lifeCycle,const void * srcData,size_t rowBytes)177 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
178 const void* srcData, size_t rowBytes) override {
179 return NULL;
180 }
181
onCreateCompressedTexture(const GrSurfaceDesc & desc,GrGpuResource::LifeCycle,const void * srcData)182 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle,
183 const void* srcData) override {
184 return NULL;
185 }
186
onWrapBackendTexture(const GrBackendTextureDesc &)187 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) override { return NULL; }
188
onWrapBackendRenderTarget(const GrBackendRenderTargetDesc &)189 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override {
190 return NULL;
191 }
192
onCreateVertexBuffer(size_t size,bool dynamic)193 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override { return NULL; }
194
onCreateIndexBuffer(size_t size,bool dynamic)195 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return NULL; }
196
onClear(GrRenderTarget *,const SkIRect * rect,GrColor color,bool canIgnoreRect)197 void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
198 bool canIgnoreRect) override {}
199
onClearStencilClip(GrRenderTarget *,const SkIRect & rect,bool insideClip)200 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
201
onDraw(const DrawArgs &,const GrNonInstancedVertices &)202 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override {}
203
onStencilPath(const GrPath * path,const StencilPathState & state)204 void onStencilPath(const GrPath* path, const StencilPathState& state) override {}
205
onDrawPath(const DrawArgs &,const GrPath *,const GrStencilSettings &)206 void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override {}
207
onDrawPaths(const DrawArgs &,const GrPathRange *,const void * indices,GrDrawTarget::PathIndexType,const float transformValues[],GrDrawTarget::PathTransformType,int count,const GrStencilSettings &)208 void onDrawPaths(const DrawArgs&,
209 const GrPathRange*,
210 const void* indices,
211 GrDrawTarget::PathIndexType,
212 const float transformValues[],
213 GrDrawTarget::PathTransformType,
214 int count,
215 const GrStencilSettings&) override {}
216
onReadPixels(GrRenderTarget * target,int left,int top,int width,int height,GrPixelConfig,void * buffer,size_t rowBytes)217 bool onReadPixels(GrRenderTarget* target,
218 int left, int top, int width, int height,
219 GrPixelConfig,
220 void* buffer,
221 size_t rowBytes) override {
222 return false;
223 }
224
onWriteTexturePixels(GrTexture * texture,int left,int top,int width,int height,GrPixelConfig config,const void * buffer,size_t rowBytes)225 bool onWriteTexturePixels(GrTexture* texture,
226 int left, int top, int width, int height,
227 GrPixelConfig config, const void* buffer,
228 size_t rowBytes) override {
229 return false;
230 }
231
onResolveRenderTarget(GrRenderTarget * target)232 void onResolveRenderTarget(GrRenderTarget* target) override { return; }
233
createStencilAttachmentForRenderTarget(GrRenderTarget *,int width,int height)234 bool createStencilAttachmentForRenderTarget(GrRenderTarget*, int width, int height) override {
235 return false;
236 }
237
attachStencilAttachmentToRenderTarget(GrStencilAttachment *,GrRenderTarget *)238 bool attachStencilAttachmentToRenderTarget(GrStencilAttachment*, GrRenderTarget*) override {
239 return false;
240 }
241
clearStencil(GrRenderTarget * target)242 void clearStencil(GrRenderTarget* target) override {}
243
didAddGpuTraceMarker()244 void didAddGpuTraceMarker() override {}
245
didRemoveGpuTraceMarker()246 void didRemoveGpuTraceMarker() override {}
247
248 typedef GrGpu INHERITED;
249 };
250
CreateMockContext()251 GrContext* GrContext::CreateMockContext() {
252 GrContext* context = SkNEW_ARGS(GrContext, (Options()));
253
254 context->initMockContext();
255 return context;
256 }
257
initMockContext()258 void GrContext::initMockContext() {
259 SkASSERT(NULL == fGpu);
260 fGpu = SkNEW_ARGS(MockGpu, (this));
261 SkASSERT(fGpu);
262 this->initCommon();
263
264 // We delete these because we want to test the cache starting with zero resources. Also, none of
265 // these objects are required for any of tests that use this context. TODO: make stop allocating
266 // resources in the buffer pools.
267 SkDELETE(fDrawBuffer);
268 fDrawBuffer = NULL;
269
270 }
271