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

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

Issue 1555953004: Create debug only SkSingleOwner (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add sentinels to GrContext Created 4 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
« no previous file with comments | « include/private/SkMutex.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrContext.h" 9 #include "GrContext.h"
10 #include "GrContextOptions.h" 10 #include "GrContextOptions.h"
11 #include "GrDrawingManager.h" 11 #include "GrDrawingManager.h"
12 #include "GrDrawContext.h" 12 #include "GrDrawContext.h"
13 #include "GrLayerCache.h" 13 #include "GrLayerCache.h"
14 #include "GrResourceCache.h" 14 #include "GrResourceCache.h"
15 #include "GrResourceProvider.h" 15 #include "GrResourceProvider.h"
16 #include "GrSoftwarePathRenderer.h" 16 #include "GrSoftwarePathRenderer.h"
17 #include "GrSurfacePriv.h" 17 #include "GrSurfacePriv.h"
18 18
19 #include "SkConfig8888.h" 19 #include "SkConfig8888.h"
20 #include "SkGrPriv.h" 20 #include "SkGrPriv.h"
21 21
22 #include "effects/GrConfigConversionEffect.h" 22 #include "effects/GrConfigConversionEffect.h"
23 #include "text/GrTextBlobCache.h" 23 #include "text/GrTextBlobCache.h"
24 24
25 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) 25 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
26 #define RETURN_IF_ABANDONED if (fDrawingManager->abandoned()) { return; } 26 #define TAKE_DEBUG_MUTEX \
27 #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->abandoned()) { return fal se; } 27 SkASSERT(1 == fSafetyMutex.fSemaphore.fCount || fSafetyMutex.fOwner == SkGet ThreadID()); \
28 #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->abandoned()) { return null ptr; } 28 SkDEBUGCODE(SkAutoTAcquire<SkRecursiveMutex> debug_SafetyMutex(fSafetyMutex) ;)
29 #define RETURN_IF_ABANDONED TAKE_DEBUG_MUTEX if (fDrawingManager->abandoned()) { return; }
30 #define RETURN_FALSE_IF_ABANDONED \
31 TAKE_DEBUG_MUTEX \
32 if (fDrawingManager->abandoned()) { return false; }
33 #define RETURN_NULL_IF_ABANDONED \
34 TAKE_DEBUG_MUTEX \
35 if (fDrawingManager->abandoned()) { return nullptr; }
29 36
30 //////////////////////////////////////////////////////////////////////////////// 37 ////////////////////////////////////////////////////////////////////////////////
31 38
32 GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { 39 GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
33 GrContextOptions defaultOptions; 40 GrContextOptions defaultOptions;
34 return Create(backend, backendContext, defaultOptions); 41 return Create(backend, backendContext, defaultOptions);
35 } 42 }
36 43
37 GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext, 44 GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
38 const GrContextOptions& options) { 45 const GrContextOptions& options) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 77
71 fGpu = GrGpu::Create(backend, backendContext, options, this); 78 fGpu = GrGpu::Create(backend, backendContext, options, this);
72 if (!fGpu) { 79 if (!fGpu) {
73 return false; 80 return false;
74 } 81 }
75 this->initCommon(options); 82 this->initCommon(options);
76 return true; 83 return true;
77 } 84 }
78 85
79 void GrContext::initCommon(const GrContextOptions& options) { 86 void GrContext::initCommon(const GrContextOptions& options) {
87 TAKE_DEBUG_MUTEX
mtklein 2016/01/05 22:47:50 What is the constraint that you are trying to enfo
joshualitt 2016/01/06 14:03:27 No, but a GrContext may only ever be used from one
mtklein 2016/01/06 14:33:46 So what do we need the reentrant mutex for? We're
88
80 fCaps = SkRef(fGpu->caps()); 89 fCaps = SkRef(fGpu->caps());
81 fResourceCache = new GrResourceCache(fCaps); 90 fResourceCache = new GrResourceCache(fCaps);
82 fResourceCache->setOverBudgetCallback(OverBudgetCB, this); 91 fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
83 fResourceProvider = new GrResourceProvider(fGpu, fResourceCache); 92 fResourceProvider = new GrResourceProvider(fGpu, fResourceCache);
84 93
85 fLayerCache.reset(new GrLayerCache(this)); 94 fLayerCache.reset(new GrLayerCache(this));
86 95
87 fDidTestPMConversions = false; 96 fDidTestPMConversions = false;
88 97
89 GrDrawTarget::Options dtOptions; 98 GrDrawTarget::Options dtOptions;
90 dtOptions.fClipBatchToBounds = options.fClipBatchToBounds; 99 dtOptions.fClipBatchToBounds = options.fClipBatchToBounds;
91 dtOptions.fDrawBatchBounds = options.fDrawBatchBounds; 100 dtOptions.fDrawBatchBounds = options.fDrawBatchBounds;
92 dtOptions.fMaxBatchLookback = options.fMaxBatchLookback; 101 dtOptions.fMaxBatchLookback = options.fMaxBatchLookback;
93 fDrawingManager.reset(new GrDrawingManager(this, dtOptions)); 102 fDrawingManager.reset(new GrDrawingManager(this, dtOptions));
94 103
95 // GrBatchFontCache will eventually replace GrFontCache 104 // GrBatchFontCache will eventually replace GrFontCache
96 fBatchFontCache = new GrBatchFontCache(this); 105 fBatchFontCache = new GrBatchFontCache(this);
97 106
98 fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this)); 107 fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this));
99 } 108 }
100 109
101 GrContext::~GrContext() { 110 GrContext::~GrContext() {
111 TAKE_DEBUG_MUTEX
112
102 if (!fGpu) { 113 if (!fGpu) {
103 SkASSERT(!fCaps); 114 SkASSERT(!fCaps);
104 return; 115 return;
105 } 116 }
106 117
107 this->flush(); 118 this->flush();
108 119
109 fDrawingManager->cleanup(); 120 fDrawingManager->cleanup();
110 121
111 for (int i = 0; i < fCleanUpData.count(); ++i) { 122 for (int i = 0; i < fCleanUpData.count(); ++i) {
112 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); 123 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
113 } 124 }
114 125
115 delete fResourceProvider; 126 delete fResourceProvider;
116 delete fResourceCache; 127 delete fResourceCache;
117 delete fBatchFontCache; 128 delete fBatchFontCache;
118 129
119 fGpu->unref(); 130 fGpu->unref();
120 fCaps->unref(); 131 fCaps->unref();
121 } 132 }
122 133
123 void GrContext::abandonContext() { 134 void GrContext::abandonContext() {
135 TAKE_DEBUG_MUTEX
136
124 fResourceProvider->abandon(); 137 fResourceProvider->abandon();
125 138
126 // Need to abandon the drawing manager first so all the render targets 139 // Need to abandon the drawing manager first so all the render targets
127 // will be released/forgotten before they too are abandoned. 140 // will be released/forgotten before they too are abandoned.
128 fDrawingManager->abandon(); 141 fDrawingManager->abandon();
129 142
130 // abandon first to so destructors 143 // abandon first to so destructors
131 // don't try to free the resources in the API. 144 // don't try to free the resources in the API.
132 fResourceCache->abandonAll(); 145 fResourceCache->abandonAll();
133 146
134 fGpu->contextAbandoned(); 147 fGpu->contextAbandoned();
135 148
136 fBatchFontCache->freeAll(); 149 fBatchFontCache->freeAll();
137 fLayerCache->freeAll(); 150 fLayerCache->freeAll();
138 fTextBlobCache->freeAll(); 151 fTextBlobCache->freeAll();
139 } 152 }
140 153
141 void GrContext::resetContext(uint32_t state) { 154 void GrContext::resetContext(uint32_t state) {
155 TAKE_DEBUG_MUTEX
156
142 fGpu->markContextDirty(state); 157 fGpu->markContextDirty(state);
143 } 158 }
144 159
145 void GrContext::freeGpuResources() { 160 void GrContext::freeGpuResources() {
161 TAKE_DEBUG_MUTEX
162
146 this->flush(); 163 this->flush();
147 164
148 fBatchFontCache->freeAll(); 165 fBatchFontCache->freeAll();
149 fLayerCache->freeAll(); 166 fLayerCache->freeAll();
150 167
151 fDrawingManager->freeGpuResources(); 168 fDrawingManager->freeGpuResources();
152 169
153 fResourceCache->purgeAllUnlocked(); 170 fResourceCache->purgeAllUnlocked();
154 } 171 }
155 172
156 void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { 173 void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
174 TAKE_DEBUG_MUTEX
175
157 if (resourceCount) { 176 if (resourceCount) {
158 *resourceCount = fResourceCache->getBudgetedResourceCount(); 177 *resourceCount = fResourceCache->getBudgetedResourceCount();
159 } 178 }
160 if (resourceBytes) { 179 if (resourceBytes) {
161 *resourceBytes = fResourceCache->getBudgetedResourceBytes(); 180 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
162 } 181 }
163 } 182 }
164 183
165 //////////////////////////////////////////////////////////////////////////////// 184 ////////////////////////////////////////////////////////////////////////////////
166 185
(...skipping 12 matching lines...) Expand all
179 // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they 198 // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
180 // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move 199 // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move
181 // drawText calls to below the GrContext level, but this is not trivial beca use they call 200 // drawText calls to below the GrContext level, but this is not trivial beca use they call
182 // drawPath on SkGpuDevice 201 // drawPath on SkGpuDevice
183 GrContext* context = reinterpret_cast<GrContext*>(data); 202 GrContext* context = reinterpret_cast<GrContext*>(data);
184 context->flush(); 203 context->flush();
185 } 204 }
186 205
187 //////////////////////////////////////////////////////////////////////////////// 206 ////////////////////////////////////////////////////////////////////////////////
188 207
189 void GrContext::flush(int flagsBitfield) { 208 void GrContext::flush(int flagsBitfield) {
mtklein 2016/01/05 22:47:50 Why do some methods TAKE_DEBUG_MUTEX and not other
mtklein 2016/01/05 22:55:45 Oh, I see. That's very confusing.
joshualitt 2016/01/06 14:03:27 I can explicitly break it out of the macro if that
mtklein 2016/01/06 14:33:46 I think it would.
190 RETURN_IF_ABANDONED 209 RETURN_IF_ABANDONED
191 210
192 if (kDiscard_FlushBit & flagsBitfield) { 211 if (kDiscard_FlushBit & flagsBitfield) {
193 fDrawingManager->reset(); 212 fDrawingManager->reset();
194 } else { 213 } else {
195 fDrawingManager->flush(); 214 fDrawingManager->flush();
196 } 215 }
197 fResourceCache->notifyFlushOccurred(); 216 fResourceCache->notifyFlushOccurred();
198 fFlushToReduceCacheSize = false; 217 fFlushToReduceCacheSize = false;
199 } 218 }
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 void GrContext::flushSurfaceWrites(GrSurface* surface) { 547 void GrContext::flushSurfaceWrites(GrSurface* surface) {
529 RETURN_IF_ABANDONED 548 RETURN_IF_ABANDONED
530 if (surface->surfacePriv().hasPendingWrite()) { 549 if (surface->surfacePriv().hasPendingWrite()) {
531 this->flush(); 550 this->flush();
532 } 551 }
533 } 552 }
534 553
535 //////////////////////////////////////////////////////////////////////////////// 554 ////////////////////////////////////////////////////////////////////////////////
536 int GrContext::getRecommendedSampleCount(GrPixelConfig config, 555 int GrContext::getRecommendedSampleCount(GrPixelConfig config,
537 SkScalar dpi) const { 556 SkScalar dpi) const {
557 TAKE_DEBUG_MUTEX
558
538 if (!this->caps()->isConfigRenderable(config, true)) { 559 if (!this->caps()->isConfigRenderable(config, true)) {
539 return 0; 560 return 0;
540 } 561 }
541 int chosenSampleCount = 0; 562 int chosenSampleCount = 0;
542 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) { 563 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
543 if (dpi >= 250.0f) { 564 if (dpi >= 250.0f) {
544 chosenSampleCount = 4; 565 chosenSampleCount = 4;
545 } else { 566 } else {
546 chosenSampleCount = 16; 567 chosenSampleCount = 16;
547 } 568 }
548 } 569 }
549 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? 570 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
550 chosenSampleCount : 0; 571 chosenSampleCount : 0;
551 } 572 }
552 573
553 574
554 GrDrawContext* GrContext::drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps) { 575 GrDrawContext* GrContext::drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps) {
576 TAKE_DEBUG_MUTEX
555 return fDrawingManager->drawContext(rt, surfaceProps); 577 return fDrawingManager->drawContext(rt, surfaceProps);
556 } 578 }
557 579
558 bool GrContext::abandoned() const { 580 bool GrContext::abandoned() const {
581 TAKE_DEBUG_MUTEX
559 return fDrawingManager->abandoned(); 582 return fDrawingManager->abandoned();
560 } 583 }
561 584
562 namespace { 585 namespace {
563 void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { 586 void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
564 GrConfigConversionEffect::PMConversion pmToUPM; 587 GrConfigConversionEffect::PMConversion pmToUPM;
565 GrConfigConversionEffect::PMConversion upmToPM; 588 GrConfigConversionEffect::PMConversion upmToPM;
566 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upm ToPM); 589 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upm ToPM);
567 *pmToUPMValue = pmToUPM; 590 *pmToUPMValue = pmToUPM;
568 *upmToPMValue = upmToPM; 591 *upmToPMValue = upmToPM;
569 } 592 }
570 } 593 }
571 594
572 void GrContext::testPMConversionsIfNecessary(uint32_t flags) { 595 void GrContext::testPMConversionsIfNecessary(uint32_t flags) {
596 TAKE_DEBUG_MUTEX
573 if (SkToBool(kUnpremul_PixelOpsFlag & flags)) { 597 if (SkToBool(kUnpremul_PixelOpsFlag & flags)) {
574 SkAutoMutexAcquire ama(fTestPMConversionsMutex); 598 SkAutoMutexAcquire ama(fTestPMConversionsMutex);
575 if (!fDidTestPMConversions) { 599 if (!fDidTestPMConversions) {
576 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); 600 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
577 fDidTestPMConversions = true; 601 fDidTestPMConversions = true;
578 } 602 }
579 } 603 }
580 } 604 }
581 605
582 const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, 606 const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture,
583 bool swapRAndB, 607 bool swapRAndB,
584 const SkMatrix& matrix ) const { 608 const SkMatrix& matrix ) const {
609 TAKE_DEBUG_MUTEX
585 // We should have already called this->testPMConversionsIfNecessary(). 610 // We should have already called this->testPMConversionsIfNecessary().
586 SkASSERT(fDidTestPMConversions); 611 SkASSERT(fDidTestPMConversions);
587 GrConfigConversionEffect::PMConversion pmToUPM = 612 GrConfigConversionEffect::PMConversion pmToUPM =
588 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); 613 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
589 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { 614 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
590 return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, mat rix); 615 return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, mat rix);
591 } else { 616 } else {
592 return nullptr; 617 return nullptr;
593 } 618 }
594 } 619 }
595 620
596 const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, 621 const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
597 bool swapRAndB, 622 bool swapRAndB,
598 const SkMatrix& matrix ) const { 623 const SkMatrix& matrix ) const {
624 TAKE_DEBUG_MUTEX
599 // We should have already called this->testPMConversionsIfNecessary(). 625 // We should have already called this->testPMConversionsIfNecessary().
600 SkASSERT(fDidTestPMConversions); 626 SkASSERT(fDidTestPMConversions);
601 GrConfigConversionEffect::PMConversion upmToPM = 627 GrConfigConversionEffect::PMConversion upmToPM =
602 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); 628 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
603 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { 629 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
604 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat rix); 630 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, mat rix);
605 } else { 631 } else {
606 return nullptr; 632 return nullptr;
607 } 633 }
608 } 634 }
609 635
610 bool GrContext::didFailPMUPMConversionTest() const { 636 bool GrContext::didFailPMUPMConversionTest() const {
637 TAKE_DEBUG_MUTEX
611 // We should have already called this->testPMConversionsIfNecessary(). 638 // We should have already called this->testPMConversionsIfNecessary().
612 SkASSERT(fDidTestPMConversions); 639 SkASSERT(fDidTestPMConversions);
613 // The PM<->UPM tests fail or succeed together so we only need to check one. 640 // The PM<->UPM tests fail or succeed together so we only need to check one.
614 return GrConfigConversionEffect::kNone_PMConversion == fPMToUPMConversion; 641 return GrConfigConversionEffect::kNone_PMConversion == fPMToUPMConversion;
615 } 642 }
616 643
617 ////////////////////////////////////////////////////////////////////////////// 644 //////////////////////////////////////////////////////////////////////////////
618 645
619 void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes ) const { 646 void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes ) const {
647 TAKE_DEBUG_MUTEX
620 if (maxTextures) { 648 if (maxTextures) {
621 *maxTextures = fResourceCache->getMaxResourceCount(); 649 *maxTextures = fResourceCache->getMaxResourceCount();
622 } 650 }
623 if (maxTextureBytes) { 651 if (maxTextureBytes) {
624 *maxTextureBytes = fResourceCache->getMaxResourceBytes(); 652 *maxTextureBytes = fResourceCache->getMaxResourceBytes();
625 } 653 }
626 } 654 }
627 655
628 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { 656 void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
657 TAKE_DEBUG_MUTEX
629 fResourceCache->setLimits(maxTextures, maxTextureBytes); 658 fResourceCache->setLimits(maxTextures, maxTextureBytes);
630 } 659 }
631 660
632 ////////////////////////////////////////////////////////////////////////////// 661 //////////////////////////////////////////////////////////////////////////////
633 662
634 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { 663 void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
664 TAKE_DEBUG_MUTEX
635 fResourceCache->dumpMemoryStatistics(traceMemoryDump); 665 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
636 } 666 }
OLDNEW
« no previous file with comments | « include/private/SkMutex.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698