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 16void GrTestTarget::init(GrContext* ctx, GrDrawTarget* target) { 17 SkASSERT(!fContext); 18 19 fContext.reset(SkRef(ctx)); 20 fDrawTarget.reset(SkRef(target)); 21} 22 23void 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 34void GrContext::setMaxTextureSizeOverride(int maxTextureSizeOverride) { 35 fMaxTextureSizeOverride = maxTextureSizeOverride; 36} 37 38void GrContext::purgeAllUnlockedResources() { 39 fResourceCache->purgeAllUnlocked(); 40} 41 42void GrContext::dumpCacheStats(SkString* out) const { 43#if GR_CACHE_STATS 44 fResourceCache->dumpStats(out); 45#endif 46} 47 48void GrContext::printCacheStats() const { 49 SkString out; 50 this->dumpCacheStats(&out); 51 SkDebugf("%s", out.c_str()); 52} 53 54void GrContext::dumpGpuStats(SkString* out) const { 55#if GR_GPU_STATS 56 return fGpu->stats()->dump(out); 57#endif 58} 59 60void GrContext::printGpuStats() const { 61 SkString out; 62 this->dumpGpuStats(&out); 63 SkDebugf("%s", out.c_str()); 64} 65 66#if GR_GPU_STATS 67void 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 77void 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 128void 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 137class GrPipeline; 138 139class MockGpu : public GrGpu { 140public: 141 MockGpu(GrContext* context) : INHERITED(context) { fCaps.reset(SkNEW(GrDrawTargetCaps)); } 142 ~MockGpu() override {} 143 bool canWriteTexturePixels(const GrTexture*, GrPixelConfig srcConfig) const override { 144 return true; 145 } 146 147 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; } 152 void buildProgramDesc(GrProgramDesc*,const GrPrimitiveProcessor&, 153 const GrPipeline&, 154 const GrBatchTracker&) const override {} 155 156 void discard(GrRenderTarget*) override {} 157 158 bool canCopySurface(const GrSurface* dst, 159 const GrSurface* src, 160 const SkIRect& srcRect, 161 const SkIPoint& dstPoint) override { return false; }; 162 163 bool copySurface(GrSurface* dst, 164 GrSurface* src, 165 const SkIRect& srcRect, 166 const SkIPoint& dstPoint) override { return false; }; 167 168 bool initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) override { 169 return false; 170 } 171 172 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} 173 174private: 175 void onResetContext(uint32_t resetBits) override {} 176 177 GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, 178 const void* srcData, size_t rowBytes) override { 179 return NULL; 180 } 181 182 GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle, 183 const void* srcData) override { 184 return NULL; 185 } 186 187 GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&) override { return NULL; } 188 189 GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&) override { 190 return NULL; 191 } 192 193 GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override { return NULL; } 194 195 GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return NULL; } 196 197 void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color, 198 bool canIgnoreRect) override {} 199 200 void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {} 201 202 void onDraw(const DrawArgs&, const GrNonInstancedVertices&) override {} 203 204 void onStencilPath(const GrPath* path, const StencilPathState& state) override {} 205 206 void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override {} 207 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 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 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 232 void onResolveRenderTarget(GrRenderTarget* target) override { return; } 233 234 bool createStencilAttachmentForRenderTarget(GrRenderTarget*, int width, int height) override { 235 return false; 236 } 237 238 bool attachStencilAttachmentToRenderTarget(GrStencilAttachment*, GrRenderTarget*) override { 239 return false; 240 } 241 242 void clearStencil(GrRenderTarget* target) override {} 243 244 void didAddGpuTraceMarker() override {} 245 246 void didRemoveGpuTraceMarker() override {} 247 248 typedef GrGpu INHERITED; 249}; 250 251GrContext* GrContext::CreateMockContext() { 252 GrContext* context = SkNEW_ARGS(GrContext, (Options())); 253 254 context->initMockContext(); 255 return context; 256} 257 258void 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