Make abandonment state of context thread-safe

The plan going forward is to centralize all thread-safe data in GrContextThreadSafeProxy, make it not derive from GrContext_Base, and have all the GrContext-derived classes share a pointer to a context group's shared GrContextThreadSafeProxy. And probably rename the proxy class after retracting it from public API (GrContextFamily?)

Bug: skia:10295
Change-Id: I9807ad0926f9b2d69a8694db974a3bcac9fd66b0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292853
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Adlai Holler <adlai@google.com>
This commit is contained in:
Adlai Holler 2020-06-01 10:11:49 -04:00 committed by Skia Commit-Bot
parent 273944ac7c
commit 43b1579dac
9 changed files with 37 additions and 14 deletions

View File

@ -697,8 +697,6 @@ protected:
virtual GrAtlasManager* onGetAtlasManager() = 0;
sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
private:
// fTaskGroup must appear before anything that uses it (e.g. fGpu), so that it is destroyed
// after all of its users. Clients of fTaskGroup will generally want to ensure that they call

View File

@ -10,6 +10,8 @@
#include "include/private/GrContext_Base.h"
#include <atomic>
class GrBackendFormat;
class GrContextThreadSafeProxyPriv;
struct SkImageInfo;
@ -19,6 +21,9 @@ class SkSurfaceProps;
/**
* Can be used to perform actions related to the generating GrContext in a thread safe manner. The
* proxy does not access the 3D API (e.g. OpenGL) that backs the generating GrContext.
*
* TODO: Once the guts of GrContext_Base are moved in here, this probably shouldn't derive
* from GrContext_Base since it isn't actually a context.
*/
class SK_API GrContextThreadSafeProxy : public GrContext_Base {
public:
@ -89,6 +94,10 @@ public:
GrContextThreadSafeProxyPriv priv();
const GrContextThreadSafeProxyPriv priv() const;
protected:
// TODO: remove this once this class isn't derived from GrContext_Base
GrContextThreadSafeProxy* asThreadSafeProxy() override { return this; }
private:
friend class GrContextThreadSafeProxyPriv; // for ctor and hidden methods
@ -97,6 +106,11 @@ private:
bool init(sk_sp<const GrCaps>) override;
void abandonContext();
bool abandoned() const;
std::atomic<bool> fAbandoned{false};
typedef GrContext_Base INHERITED;
};

View File

@ -74,8 +74,13 @@ protected:
virtual GrImageContext* asImageContext() { return nullptr; }
virtual GrRecordingContext* asRecordingContext() { return nullptr; }
virtual GrContext* asDirectContext() { return nullptr; }
// TODO: Remove this once the proxy object isn't itself a context.
virtual GrContextThreadSafeProxy* asThreadSafeProxy() { return nullptr; }
sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
private:
// TODO: Move these const vars into thread safe proxy.
const GrBackendApi fBackend;
const GrContextOptions fOptions;
const uint32_t fContextID;

View File

@ -67,7 +67,6 @@ GrContext::~GrContext() {
bool GrContext::init(sk_sp<const GrCaps> caps) {
ASSERT_SINGLE_OWNER
SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
SkASSERT(this->proxyProvider());
if (!INHERITED::init(std::move(caps))) {

View File

@ -101,6 +101,14 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
surfaceProps);
}
void GrContextThreadSafeProxy::abandonContext() {
fAbandoned.store(true, std::memory_order_relaxed);
}
bool GrContextThreadSafeProxy::abandoned() const {
return fAbandoned.load(std::memory_order_relaxed);
}
////////////////////////////////////////////////////////////////////////////////
sk_sp<GrContextThreadSafeProxy> GrContextThreadSafeProxyPriv::Make(
GrBackendApi backend,

View File

@ -29,6 +29,9 @@ public:
const GrCaps* caps() const { return fProxy->caps(); }
sk_sp<const GrCaps> refCaps() const { return fProxy->refCaps(); }
void abandonContext() { fProxy->abandonContext(); }
bool abandoned() const { return fProxy->abandoned(); }
// GrContextThreadSafeProxyPriv
static sk_sp<GrContextThreadSafeProxy> Make(GrBackendApi,
const GrContextOptions&,

View File

@ -9,6 +9,7 @@
#include "src/gpu/GrBaseContextPriv.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/effects/GrSkSLFP.h"
@ -33,8 +34,10 @@ GrContext_Base::~GrContext_Base() { }
bool GrContext_Base::init(sk_sp<const GrCaps> caps) {
SkASSERT(caps);
// We either are a thread safe proxy and we don't have one, or we aren't and we do.
SkASSERT((nullptr == this->asThreadSafeProxy()) != (nullptr == fThreadSafeProxy));
fCaps = caps;
fCaps = std::move(caps);
return true;
}

View File

@ -49,7 +49,6 @@ private:
bool init(sk_sp<const GrCaps> caps) override {
SkASSERT(caps);
SkASSERT(fThreadSafeProxy); // should've been set in the ctor
if (!INHERITED::init(std::move(caps))) {
return false;

View File

@ -8,13 +8,11 @@
#include "include/private/GrImageContext.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrImageContextPriv.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/effects/GrSkSLFP.h"
#define ASSERT_SINGLE_OWNER \
SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
///////////////////////////////////////////////////////////////////////////////////////////////////
GrImageContext::GrImageContext(GrBackendApi backend,
const GrContextOptions& options,
@ -26,15 +24,11 @@ GrImageContext::GrImageContext(GrBackendApi backend,
GrImageContext::~GrImageContext() {}
void GrImageContext::abandonContext() {
ASSERT_SINGLE_OWNER
fAbandoned = true;
fThreadSafeProxy->priv().abandonContext();
}
bool GrImageContext::abandoned() {
ASSERT_SINGLE_OWNER
return fAbandoned;
return fThreadSafeProxy->priv().abandoned();
}
///////////////////////////////////////////////////////////////////////////////////////////////////