Maybe fix numStencilBits TSAN crash

Bug: skia:7390
Change-Id: Ied9c92147324ddb1245df796cd201df35657bbe0
Reviewed-on: https://skia-review.googlesource.com/143304
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2018-07-26 08:03:04 -04:00 committed by Skia Commit-Bot
parent b64db38b85
commit 01a9128a6f
7 changed files with 57 additions and 17 deletions

View File

@ -95,6 +95,10 @@ public:
protected:
bool isInstantiated() const;
// In addition to just the GrSurface being allocated, has the stencil buffer been allocated (if
// it is required)?
bool isFullyInstantiated() const;
// This is a backpointer to the GrOpMemoryPool that holds the memory for this opLists' ops.
// In the DDL case, these back pointers keep the DDL's GrOpMemoryPool alive as long as its
// constituent opLists survive.

View File

@ -103,6 +103,13 @@ void GrDrawingManager::freeGpuResources() {
fSoftwarePathRenderer = nullptr;
}
static void end_oplist_flush_if_not_unique(const sk_sp<GrOpList>& opList) {
if (!opList->unique()) {
// TODO: Eventually this should be guaranteed unique: http://skbug.com/7111
opList->endFlush();
}
}
// MDB TODO: make use of the 'proxy' parameter.
GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
GrResourceCache::FlushType type,
@ -210,6 +217,11 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
&error)) {
if (GrResourceAllocator::AssignError::kFailedProxyInstantiation == error) {
for (int i = startIndex; i < stopIndex; ++i) {
if (fOpLists[i] && !fOpLists[i]->isFullyInstantiated()) {
// If the backing surface wasn't allocated drop the entire opList.
end_oplist_flush_if_not_unique(fOpLists[i]); // http://skbug.com/7111
fOpLists[i] = nullptr;
}
if (fOpLists[i]) {
fOpLists[i]->purgeOpsWithUninstantiatedProxies();
}
@ -259,13 +271,6 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
return result;
}
static void end_oplist_flush_if_not_unique(const sk_sp<GrOpList>& opList) {
if (!opList->unique()) {
// TODO: Eventually this should be guaranteed unique: http://skbug.com/7111
opList->endFlush();
}
}
bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushState* flushState) {
SkASSERT(startIndex <= stopIndex && stopIndex <= fOpLists.count());
@ -286,7 +291,7 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt
}
if (resourceProvider->explicitlyAllocateGPUResources()) {
if (!fOpLists[i]->isInstantiated()) {
if (!fOpLists[i]->isFullyInstantiated()) {
// If the backing surface wasn't allocated drop the draw of the entire opList.
end_oplist_flush_if_not_unique(fOpLists[i]); // http://skbug.com/7111
fOpLists[i] = nullptr;

View File

@ -10,6 +10,7 @@
#include "GrContext.h"
#include "GrDeferredProxyUploader.h"
#include "GrMemoryPool.h"
#include "GrRenderTargetPriv.h"
#include "GrSurfaceProxy.h"
#include "GrTextureProxyPriv.h"
@ -138,6 +139,27 @@ bool GrOpList::isInstantiated() const {
return fTarget.get()->priv().isInstantiated();
}
bool GrOpList::isFullyInstantiated() const {
if (!this->isInstantiated()) {
return false;
}
GrSurfaceProxy* proxy = fTarget.get();
bool needsStencil = proxy->asRenderTargetProxy()
? proxy->asRenderTargetProxy()->needsStencil()
: false;
if (needsStencil) {
GrRenderTarget* rt = proxy->priv().peekRenderTarget();
if (!rt->renderTargetPriv().getStencilAttachment()) {
return false;
}
}
return true;
}
#ifdef SK_DEBUG
static const char* op_to_name(GrLoadOp op) {
return GrLoadOp::kLoad == op ? "load" : GrLoadOp::kClear == op ? "clear" : "discard";

View File

@ -180,7 +180,10 @@ sk_sp<GrSurface> GrResourceAllocator::findSurfaceFor(const GrSurfaceProxy* proxy
surface->resourcePriv().makeBudgeted();
}
GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, surface.get(), needsStencil);
if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider, surface.get(),
needsStencil)) {
return nullptr;
}
return surface;
}
@ -248,9 +251,11 @@ bool GrResourceAllocator::assign(int* startIndex, int* stopIndex,
: false;
if (cur->proxy()->priv().isInstantiated()) {
GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider,
cur->proxy()->priv().peekSurface(),
needsStencil);
if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(fResourceProvider,
cur->proxy()->priv().peekSurface(),
needsStencil)) {
*outError = AssignError::kFailedProxyInstantiation;
}
fActiveIntvls.insertByIncreasingEnd(cur);

View File

@ -402,10 +402,11 @@ bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
if (!stencil) {
// Need to try and create a new stencil
stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
if (stencil) {
this->assignUniqueKeyToResource(sbKey, stencil.get());
SkDEBUGCODE(newStencil = true;)
if (!stencil) {
return false;
}
this->assignUniqueKeyToResource(sbKey, stencil.get());
SkDEBUGCODE(newStencil = true;)
}
if (rt->renderTargetPriv().attachStencilAttachment(std::move(stencil))) {
#ifdef SK_DEBUG

View File

@ -416,7 +416,9 @@ bool GrSurfaceProxyPriv::doLazyInstantiation(GrResourceProvider* resourceProvide
? fProxy->asRenderTargetProxy()->needsStencil()
: false;
GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil);
if (!GrSurfaceProxyPriv::AttachStencilIfNeeded(resourceProvider, surface.get(), needsStencil)) {
return false;
}
this->assign(std::move(surface));
return true;

View File

@ -86,7 +86,8 @@ public:
GrSurfaceProxy::LazyInstantiationType::kUninstantiate == lazyInstantiationType();
}
static bool AttachStencilIfNeeded(GrResourceProvider*, GrSurface*, bool needsStencil);
static bool SK_WARN_UNUSED_RESULT AttachStencilIfNeeded(GrResourceProvider*, GrSurface*,
bool needsStencil);
private:
explicit GrSurfaceProxyPriv(GrSurfaceProxy* proxy) : fProxy(proxy) {}