1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2013 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTest.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <algorithm>
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrBackendSurface.h"
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextOptions.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDrawOpAtlas.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDrawingManager.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpu.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpuResourceCacheAccess.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContext.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContextPriv.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetProxy.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceCache.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrSemaphore.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrSurfaceContextPriv.h"
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h"
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h"
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkImage_Gpu.h"
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMathPriv.h"
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkString.h"
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "ops/GrMeshDrawOp.h"
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "text/GrAtlasGlyphCache.h"
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "text/GrTextBlobCache.h"
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace GrTest {
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid SetupAlwaysEvictAtlas(GrContext* context) {
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // These sizes were selected because they allow each atlas to hold a single plot and will thus
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // stress the atlas
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int dim = GrDrawOpAtlas::kGlyphMaxDim;
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrDrawOpAtlasConfig configs[3];
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA8_GrMaskFormat].fWidth = dim;
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA8_GrMaskFormat].fHeight = dim;
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA8_GrMaskFormat].fPlotWidth = dim;
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA8_GrMaskFormat].fPlotHeight = dim;
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA565_GrMaskFormat].fWidth = dim;
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA565_GrMaskFormat].fHeight = dim;
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA565_GrMaskFormat].fPlotWidth = dim;
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kA565_GrMaskFormat].fPlotHeight = dim;
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kARGB_GrMaskFormat].fWidth = dim;
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kARGB_GrMaskFormat].fHeight = dim;
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kARGB_GrMaskFormat].fPlotWidth = dim;
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    configs[kARGB_GrMaskFormat].fPlotHeight = dim;
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    context->setTextContextAtlasSizes_ForTesting(configs);
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrBackendTexture CreateBackendTexture(GrBackend backend, int width, int height,
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      GrPixelConfig config, GrMipMapped mipMapped,
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                      GrBackendObject handle) {
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    switch (backend) {
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_VULKAN
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kVulkan_GrBackend: {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrVkImageInfo* vkInfo = (GrVkImageInfo*)(handle);
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT((GrMipMapped::kYes == mipMapped) == (vkInfo->fLevelCount > 1));
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return GrBackendTexture(width, height, *vkInfo);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kOpenGL_GrBackend: {
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrGLTextureInfo* glInfo = (GrGLTextureInfo*)(handle);
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            SkASSERT(glInfo->fFormat);
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return GrBackendTexture(width, height, mipMapped, *glInfo);
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        case kMock_GrBackend: {
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrMockTextureInfo* mockInfo = (GrMockTextureInfo*)(handle);
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return GrBackendTexture(width, height, config, mipMapped, *mockInfo);
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        default:
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return GrBackendTexture();
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}  // namespace GrTest
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool GrSurfaceProxy::isWrapped_ForTesting() const {
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return SkToBool(fTarget);
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool GrRenderTargetContext::isWrapped_ForTesting() const {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fRenderTargetProxy->isWrapped_ForTesting();
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::setTextBlobCacheLimit_ForTesting(size_t bytes) {
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fTextBlobCache->setBudget(bytes);
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::setTextContextAtlasSizes_ForTesting(const GrDrawOpAtlasConfig* configs) {
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fAtlasGlyphCache->setAtlasSizes_ForTesting(configs);
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::purgeAllUnlockedResources() {
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fResourceCache->purgeAllUnlocked();
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::resetGpuStats() const {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_GPU_STATS
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fGpu->stats()->reset();
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::dumpCacheStats(SkString* out) const {
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fResourceCache->dumpStats(out);
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                            SkTArray<double>* values) const {
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fResourceCache->dumpStatsKeyValuePairs(keys, values);
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::printCacheStats() const {
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString out;
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->dumpCacheStats(&out);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDebugf("%s", out.c_str());
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::dumpGpuStats(SkString* out) const {
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_GPU_STATS
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fGpu->stats()->dump(out);
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                          SkTArray<double>* values) const {
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_GPU_STATS
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fGpu->stats()->dumpKeyValuePairs(keys, values);
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContext::printGpuStats() const {
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkString out;
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->dumpGpuStats(&out);
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDebugf("%s", out.c_str());
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotsk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format, uint32_t index) {
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrAtlasGlyphCache* cache = this->contextPriv().getAtlasGlyphCache();
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const sk_sp<GrTextureProxy>* proxies = cache->getProxies(format);
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (index >= cache->getAtlasPageCount(format) || !proxies[index]) {
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return nullptr;
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(proxies[index]->priv().isExact());
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<SkImage> image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType,
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                         proxies[index], nullptr, SkBudgeted::kNo));
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return image;
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_GPU_STATS
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGpu::Stats::dump(SkString* out) {
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Render Target Binds: %d\n", fRenderTargetBinds);
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Shader Compilations: %d\n", fShaderCompilations);
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Textures Created: %d\n", fTextureCreates);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Texture Uploads: %d\n", fTextureUploads);
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Transfers to Texture: %d\n", fTransfersToTexture);
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Stencil Buffer Creates: %d\n", fStencilAttachmentCreates);
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Number of draws: %d\n", fNumDraws);
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrGpu::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("render_target_binds")); values->push_back(fRenderTargetBinds);
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("shader_compilations")); values->push_back(fShaderCompilations);
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("texture_uploads")); values->push_back(fTextureUploads);
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("number_of_draws")); values->push_back(fNumDraws);
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("number_of_failed_draws")); values->push_back(fNumFailedDraws);
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::getStats(Stats* stats) const {
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stats->reset();
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stats->fTotal = this->getResourceCount();
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stats->fNumNonPurgeable = fNonpurgeableResources.count();
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    stats->fNumPurgeable = fPurgeableQueue.count();
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < fNonpurgeableResources.count(); ++i) {
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        stats->update(fNonpurgeableResources[i]);
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (int i = 0; i < fPurgeableQueue.count(); ++i) {
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        stats->update(fPurgeableQueue.at(i));
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::dumpStats(SkString* out) const {
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->validate();
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Stats stats;
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->getStats(&stats);
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("\t\tEntry Count: current %d"
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable,
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 stats.fScratch, countUtilization, fHighWaterCount);
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                 SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::dumpStatsKeyValuePairs(SkTArray<SkString>* keys,
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                             SkTArray<double>* values) const {
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->validate();
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Stats stats;
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    this->getStats(&stats);
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    keys->push_back(SkString("gpu_cache_purgable_entries")); values->push_back(stats.fNumPurgeable);
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::changeTimestamp(uint32_t newTimestamp) { fTimestamp = newTimestamp; }
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotint GrResourceCache::countUniqueKeysWithTag(const char* tag) const {
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int count = 0;
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    UniqueHash::ConstIter iter(&fUniqueHash);
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    while (!iter.done()) {
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (0 == strcmp(tag, (*iter).getUniqueKey().tag())) {
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            ++count;
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ++iter;
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return count;
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define ASSERT_SINGLE_OWNER \
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t GrRenderTargetContextPriv::testingOnly_getOpListID() {
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fRenderTargetContext->getOpList()->uniqueID();
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(std::unique_ptr<GrDrawOp> op) {
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return this->testingOnly_addDrawOp(GrNoClip(), std::move(op));
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t GrRenderTargetContextPriv::testingOnly_addDrawOp(const GrClip& clip,
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                          std::unique_ptr<GrDrawOp> op) {
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ASSERT_SINGLE_OWNER
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    if (fRenderTargetContext->drawingManager()->wasAbandoned()) {
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return SK_InvalidUniqueID;
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkDEBUGCODE(fRenderTargetContext->validate());
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                              "GrRenderTargetContext::testingOnly_addDrawOp");
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fRenderTargetContext->addDrawOp(clip, std::move(op));
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#undef ASSERT_SINGLE_OWNER
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot///////////////////////////////////////////////////////////////////////////////
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrRenderTargetFlags GrRenderTargetProxy::testingOnly_getFlags() const {
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    return fRenderTargetFlags;
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fContext->flush();
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fContext->fDrawingManager->testingOnly_removeOnFlushCallbackObject(cb);
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrDrawingManager::testingOnly_removeOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int n = std::find(fOnFlushCBObjects.begin(), fOnFlushCBObjects.end(), cb) -
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fOnFlushCBObjects.begin();
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(n < fOnFlushCBObjects.count());
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    fOnFlushCBObjects.removeShuffle(n);
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot//////////////////////////////////////////////////////////////////////////////
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define DRAW_OP_TEST_EXTERN(Op) \
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType)
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define DRAW_OP_TEST_ENTRY(Op) Op##__Test
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(AAConvexPathOp);
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(AAFillRectOp);
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(AAFlatteningConvexPathOp);
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(AAHairlineOp);
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(AAStrokeRectOp);
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(CircleOp);
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(DashOp);
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(DefaultPathOp);
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(DIEllipseOp);
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(EllipseOp);
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(GrAtlasTextOp);
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(GrDrawAtlasOp);
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(GrDrawVerticesOp);
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(NonAAFillRectOp);
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(NonAALatticeOp);
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(NonAAStrokeRectOp);
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(ShadowRRectOp);
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(SmallPathOp);
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(RegionOp);
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(RRectOp);
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(TesselatingPathOp);
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDRAW_OP_TEST_EXTERN(TextureOp);
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrDrawRandomOp(SkRandom* random, GrRenderTargetContext* renderTargetContext, GrPaint&& paint) {
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrContext* context = renderTargetContext->surfPriv().getContext();
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    using MakeDrawOpFn = std::unique_ptr<GrDrawOp>(GrPaint&&, SkRandom*, GrContext*, GrFSAAType);
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr MakeDrawOpFn* gFactories[] = {
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(AAConvexPathOp),
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(AAFillRectOp),
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(AAFlatteningConvexPathOp),
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(AAHairlineOp),
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(AAStrokeRectOp),
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(CircleOp),
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(DashOp),
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(DefaultPathOp),
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(DIEllipseOp),
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(EllipseOp),
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(GrAtlasTextOp),
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(GrDrawAtlasOp),
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(GrDrawVerticesOp),
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(NonAAFillRectOp),
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(NonAALatticeOp),
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(NonAAStrokeRectOp),
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(ShadowRRectOp),
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(SmallPathOp),
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(RegionOp),
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(RRectOp),
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(TesselatingPathOp),
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            DRAW_OP_TEST_ENTRY(TextureOp),
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static constexpr size_t kTotal = SK_ARRAY_COUNT(gFactories);
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    uint32_t index = random->nextULessThan(static_cast<uint32_t>(kTotal));
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto op = gFactories[index](
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            std::move(paint), random, context, renderTargetContext->fsaaType());
360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    SkASSERT(op);
361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
363