Move GrSurfaceProxy::MakeLazy to GrProxyProvider::createLazy

This is pretty much a straight up move of the GrSurfaceProxy code with some plumbing to get the ProxyProvider in the right places.

Change-Id: I63cecb242dada503f97dbd1c0ce7ede75323100d
Reviewed-on: https://skia-review.googlesource.com/94200
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2018-01-17 11:40:14 -05:00 committed by Skia Commit-Bot
parent 95379ebc0d
commit 777707be84
12 changed files with 115 additions and 92 deletions

View File

@ -185,31 +185,6 @@ public:
// DDL TODO: remove this entry point
static sk_sp<GrTextureProxy> MakeWrapped(sk_sp<GrTexture>, GrSurfaceOrigin);
using LazyInstantiateCallback = std::function<sk_sp<GrTexture>(GrResourceProvider*,
GrSurfaceOrigin* outOrigin)>;
enum class Renderable : bool {
kNo = false,
kYes = true
};
/**
* Creates a texture proxy that will be instantiated by a user-supplied callback during flush.
* (Stencil is not supported by this method.) The width and height must either both be greater
* than 0 or both less than or equal to zero. A non-positive value is a signal that the width
* and height are currently unknown.
*
* When called, the callback must be able to cleanup any resources that it captured at creation.
* It also must support being passed in a null GrResourceProvider. When this happens, the
* callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
* DDL TODO: remove this entry point
*/
static sk_sp<GrTextureProxy> MakeLazy(LazyInstantiateCallback&&, const GrSurfaceDesc& desc,
GrMipMapped, SkBackingFit fit, SkBudgeted budgeted);
static sk_sp<GrTextureProxy> MakeFullyLazy(LazyInstantiateCallback&&, Renderable,
GrPixelConfig);
enum class LazyState {
kNot, // The proxy has no lazy callback that must be made.
kPartially, // The proxy has a lazy callback but knows basic information about itself.
@ -383,6 +358,9 @@ protected:
// Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
}
using LazyInstantiateCallback = std::function<sk_sp<GrTexture>(GrResourceProvider*,
GrSurfaceOrigin* outOrigin)>;
// Lazy-callback version
GrSurfaceProxy(LazyInstantiateCallback&& callback, const GrSurfaceDesc& desc,
SkBackingFit fit, SkBudgeted budgeted, uint32_t flags);

View File

@ -10,6 +10,7 @@
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetContext.h"
#include "GrResourceCache.h"
#include "GrResourceProvider.h"
@ -91,6 +92,8 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
return nullptr;
}
auto proxyProvider = context->contextPriv().proxyProvider();
uint32_t expectedID = SK_InvalidGenID;
if (!fRefHelper->fBorrowingContextID.compare_exchange(&expectedID, context->uniqueID())) {
if (fRefHelper->fBorrowingContextID != context->uniqueID()) {
@ -116,7 +119,7 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
RefHelper* refHelper = fRefHelper;
refHelper->ref();
sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeLazy(
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[refHelper, semaphore, backendTexture, surfaceOrigin]
(GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
if (!resourceProvider) {

View File

@ -190,6 +190,7 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
return true;
}
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
const auto* caps = context->caps()->shaderCaps();
int maxWindowRectangles = renderTargetContext->priv().maxWindowRectangles();
int maxAnalyticFPs = context->caps()->maxClipAnalyticFPs();
@ -230,7 +231,8 @@ bool GrClipStackClip::apply(GrContext* context, GrRenderTargetContext* renderTar
// can cause a flush or otherwise change which opList our draw is going into.
uint32_t opListID = renderTargetContext->getOpList()->uniqueID();
int rtWidth = renderTargetContext->width(), rtHeight = renderTargetContext->height();
if (auto clipFPs = reducedClip.finishAndDetachAnalyticFPs(opListID, rtWidth, rtHeight)) {
if (auto clipFPs = reducedClip.finishAndDetachAnalyticFPs(proxyProvider, opListID,
rtWidth, rtHeight)) {
out->addCoverageFP(std::move(clipFPs));
}

View File

@ -375,6 +375,39 @@ sk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy(const GrBa
return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin));
}
sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
const GrSurfaceDesc& desc,
GrMipMapped mipMapped,
SkBackingFit fit, SkBudgeted budgeted) {
SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
(desc.fWidth > 0 && desc.fHeight > 0));
uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ?
new GrTextureRenderTargetProxy(std::move(callback), desc,
mipMapped, fit, budgeted, flags) :
new GrTextureProxy(std::move(callback), desc, mipMapped, fit,
budgeted, flags));
}
sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback,
Renderable renderable,
GrPixelConfig config) {
GrSurfaceDesc desc;
if (Renderable::kYes == renderable) {
desc.fFlags = kRenderTarget_GrSurfaceFlag;
}
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fWidth = -1;
desc.fHeight = -1;
desc.fConfig = config;
desc.fSampleCnt = 0;
return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo,
SkBackingFit::kApprox, SkBudgeted::kYes);
}
bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
}

View File

@ -87,7 +87,6 @@ public:
SkDestinationSurfaceColorMode mipColorMode =
SkDestinationSurfaceColorMode::kLegacy);
/*
* Create a mipmapped texture proxy without any data.
*
@ -128,6 +127,30 @@ public:
GrSurfaceOrigin origin,
int sampleCnt);
using LazyInstantiateCallback = std::function<sk_sp<GrTexture>(GrResourceProvider*,
GrSurfaceOrigin* outOrigin)>;
enum class Renderable : bool {
kNo = false,
kYes = true
};
/**
* Creates a texture proxy that will be instantiated by a user-supplied callback during flush.
* (Stencil is not supported by this method.) The width and height must either both be greater
* than 0 or both less than or equal to zero. A non-positive value is a signal that the width
* and height are currently unknown.
*
* When called, the callback must be able to cleanup any resources that it captured at creation.
* It also must support being passed in a null GrResourceProvider. When this happens, the
* callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
*/
sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
GrMipMapped, SkBackingFit, SkBudgeted);
sk_sp<GrTextureProxy> createFullyLazyProxy(LazyInstantiateCallback&&,
Renderable, GrPixelConfig);
// 'proxy' is about to be used as a texture src or drawn to. This query can be used to
// determine if it is going to need a texture domain or a full clear.
static bool IsFunctionallyExact(GrSurfaceProxy* proxy);

View File

@ -954,9 +954,9 @@ bool GrReducedClip::drawStencilClipMask(GrContext* context,
return true;
}
std::unique_ptr<GrFragmentProcessor> GrReducedClip::finishAndDetachAnalyticFPs(uint32_t opListID,
int rtWidth,
int rtHeight) {
std::unique_ptr<GrFragmentProcessor> GrReducedClip::finishAndDetachAnalyticFPs(
GrProxyProvider* proxyProvider, uint32_t opListID,
int rtWidth, int rtHeight) {
// Make sure finishAndDetachAnalyticFPs hasn't been called already.
SkDEBUGCODE(for (const auto& fp : fAnalyticFPs) { SkASSERT(fp); })
@ -964,7 +964,8 @@ std::unique_ptr<GrFragmentProcessor> GrReducedClip::finishAndDetachAnalyticFPs(u
fAnalyticFPs.reserve(fAnalyticFPs.count() + fCCPRClipPaths.count());
for (const SkPath& ccprClipPath : fCCPRClipPaths) {
SkASSERT(fHasScissor);
auto fp = fCCPR->makeClipProcessor(opListID, ccprClipPath, fScissor, rtWidth, rtHeight);
auto fp = fCCPR->makeClipProcessor(proxyProvider, opListID, ccprClipPath, fScissor,
rtWidth, rtHeight);
fAnalyticFPs.push_back(std::move(fp));
}
fCCPRClipPaths.reset();

View File

@ -97,8 +97,9 @@ public:
* the render target context, surface allocations, and even switching render targets (pre MDB)
* may cause flushes or otherwise change which opList the actual draw is going into.
*/
std::unique_ptr<GrFragmentProcessor> finishAndDetachAnalyticFPs(uint32_t opListID, int rtWidth,
int rtHeight);
std::unique_ptr<GrFragmentProcessor> finishAndDetachAnalyticFPs(GrProxyProvider*,
uint32_t opListID,
int rtWidth, int rtHeight);
private:
void walkStack(const SkClipStack&, const SkRect& queryBounds);

View File

@ -250,37 +250,6 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrTexture> tex, GrSurfac
}
}
sk_sp<GrTextureProxy> GrSurfaceProxy::MakeLazy(LazyInstantiateCallback&& callback,
const GrSurfaceDesc& desc,
GrMipMapped mipMapped,
SkBackingFit fit,
SkBudgeted budgeted) {
SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
(desc.fWidth > 0 && desc.fHeight > 0));
uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ?
new GrTextureRenderTargetProxy(std::move(callback), desc,
mipMapped, fit, budgeted, flags) :
new GrTextureProxy(std::move(callback), desc, mipMapped, fit,
budgeted, flags));
}
sk_sp<GrTextureProxy> GrSurfaceProxy::MakeFullyLazy(LazyInstantiateCallback&& callback,
Renderable renderable, GrPixelConfig config) {
GrSurfaceDesc desc;
if (Renderable::kYes == renderable) {
desc.fFlags = kRenderTarget_GrSurfaceFlag;
}
desc.fOrigin = kTopLeft_GrSurfaceOrigin;
desc.fWidth = -1;
desc.fHeight = -1;
desc.fConfig = config;
desc.fSampleCnt = 0;
return MakeLazy(std::move(callback), desc, GrMipMapped::kNo, SkBackingFit::kApprox,
SkBudgeted::kYes);
}
int GrSurfaceProxy::worstCaseWidth() const {
SkASSERT(LazyState::kFully != this->lazyInstantiationState());
if (fTarget) {

View File

@ -12,6 +12,7 @@
#include "GrGpu.h"
#include "GrGpuCommandBuffer.h"
#include "GrOpFlushState.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetOpList.h"
#include "GrStyle.h"
#include "GrTexture.h"
@ -201,8 +202,9 @@ bool GrCoverageCountingPathRenderer::canMakeClipProcessor(const SkPath& deviceSp
}
std::unique_ptr<GrFragmentProcessor> GrCoverageCountingPathRenderer::makeClipProcessor(
uint32_t opListID, const SkPath& deviceSpacePath, const SkIRect& accessRect, int rtWidth,
int rtHeight) {
GrProxyProvider* proxyProvider,
uint32_t opListID, const SkPath& deviceSpacePath, const SkIRect& accessRect,
int rtWidth, int rtHeight) {
using MustCheckBounds = GrCCClipProcessor::MustCheckBounds;
SkASSERT(!fFlushing);
@ -211,7 +213,7 @@ std::unique_ptr<GrFragmentProcessor> GrCoverageCountingPathRenderer::makeClipPro
ClipPath& clipPath = fRTPendingPathsMap[opListID].fClipPaths[deviceSpacePath.getGenerationID()];
if (clipPath.isUninitialized()) {
// This ClipPath was just created during lookup. Initialize it.
clipPath.init(deviceSpacePath, accessRect, rtWidth, rtHeight);
clipPath.init(proxyProvider, deviceSpacePath, accessRect, rtWidth, rtHeight);
} else {
clipPath.addAccess(accessRect);
}
@ -221,11 +223,12 @@ std::unique_ptr<GrFragmentProcessor> GrCoverageCountingPathRenderer::makeClipPro
deviceSpacePath.getFillType());
}
void CCPR::ClipPath::init(const SkPath& deviceSpacePath, const SkIRect& accessRect, int rtWidth,
int rtHeight) {
void CCPR::ClipPath::init(GrProxyProvider* proxyProvider,
const SkPath& deviceSpacePath, const SkIRect& accessRect,
int rtWidth, int rtHeight) {
SkASSERT(this->isUninitialized());
fAtlasLazyProxy = GrSurfaceProxy::MakeFullyLazy(
fAtlasLazyProxy = proxyProvider->createFullyLazyProxy(
[this](GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
if (!resourceProvider) {
return sk_sp<GrTexture>();
@ -252,7 +255,7 @@ void CCPR::ClipPath::init(const SkPath& deviceSpacePath, const SkIRect& accessRe
*outOrigin = textureProxy->origin();
return sk_ref_sp(textureProxy->priv().peekTexture());
},
GrSurfaceProxy::Renderable::kYes, kAlpha_half_GrPixelConfig);
GrProxyProvider::Renderable::kYes, kAlpha_half_GrPixelConfig);
const SkRect& pathDevBounds = deviceSpacePath.getBounds();
if (SkTMax(pathDevBounds.height(), pathDevBounds.width()) > kPathCropThreshold) {

View File

@ -135,8 +135,9 @@ public:
}
bool isUninitialized() const { return !fAtlasLazyProxy; }
void init(const SkPath& deviceSpacePath, const SkIRect& accessRect, int rtWidth,
int rtHeight);
void init(GrProxyProvider* proxyProvider,
const SkPath& deviceSpacePath, const SkIRect& accessRect,
int rtWidth, int rtHeight);
void addAccess(const SkIRect& accessRect) {
SkASSERT(!this->isUninitialized());
fAccessRect.join(accessRect);
@ -184,10 +185,10 @@ public:
bool canMakeClipProcessor(const SkPath& deviceSpacePath) const;
std::unique_ptr<GrFragmentProcessor> makeClipProcessor(uint32_t oplistID,
std::unique_ptr<GrFragmentProcessor> makeClipProcessor(GrProxyProvider*, uint32_t oplistID,
const SkPath& deviceSpacePath,
const SkIRect& accessRect, int rtWidth,
int rtHeight);
const SkIRect& accessRect,
int rtWidth, int rtHeight);
// GrOnFlushCallbackObject overrides.
void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs,

View File

@ -33,9 +33,11 @@ public:
CCPRClip(GrCoverageCountingPathRenderer* ccpr, const SkPath& path) : fCCPR(ccpr), fPath(path) {}
private:
bool apply(GrContext*, GrRenderTargetContext* rtc, bool, bool, GrAppliedClip* out,
bool apply(GrContext* context, GrRenderTargetContext* rtc, bool, bool, GrAppliedClip* out,
SkRect* bounds) const override {
out->addCoverageFP(fCCPR->makeClipProcessor(rtc->priv().testingOnly_getOpListID(), fPath,
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
out->addCoverageFP(fCCPR->makeClipProcessor(proxyProvider,
rtc->priv().testingOnly_getOpListID(), fPath,
SkIRect::MakeWH(rtc->width(), rtc->height()),
rtc->width(), rtc->height()));
return true;

View File

@ -11,6 +11,7 @@
#include "GrClip.h"
#include "GrContextPriv.h"
#include "GrProxyProvider.h"
#include "GrOnFlushResourceProvider.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
@ -54,9 +55,10 @@ public:
public:
DEFINE_OP_CLASS_ID
Op(LazyProxyTest* test, bool nullTexture) : GrDrawOp(ClassID()), fTest(test) {
fProxy = GrSurfaceProxy::MakeFullyLazy([this, nullTexture](GrResourceProvider* rp,
GrSurfaceOrigin* origin) {
Op(GrProxyProvider* proxyProvider, LazyProxyTest* test, bool nullTexture)
: GrDrawOp(ClassID()), fTest(test) {
fProxy = proxyProvider->createFullyLazyProxy([this, nullTexture](
GrResourceProvider* rp, GrSurfaceOrigin* origin) {
REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
fTest->fHasOpTexture = true;
*origin = kTopLeft_GrSurfaceOrigin;
@ -72,7 +74,7 @@ public:
REPORTER_ASSERT(fTest->fReporter, texture);
return texture;
}
}, GrSurfaceProxy::Renderable::kNo, kRGB_565_GrPixelConfig);
}, GrProxyProvider::Renderable::kNo, kRGB_565_GrPixelConfig);
this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
}
@ -102,18 +104,19 @@ public:
class ClipFP : public GrFragmentProcessor {
public:
ClipFP(LazyProxyTest* test, GrTextureProxy* atlas)
ClipFP(GrProxyProvider* proxyProvider, LazyProxyTest* test, GrTextureProxy* atlas)
: GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
, fProxyProvider(proxyProvider)
, fTest(test)
, fAtlas(atlas) {
fLazyProxy = GrSurfaceProxy::MakeFullyLazy([this](GrResourceProvider* rp,
fLazyProxy = proxyProvider->createFullyLazyProxy([this](GrResourceProvider* rp,
GrSurfaceOrigin* origin) {
REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
fTest->fHasClipTexture = true;
*origin = kBottomLeft_GrSurfaceOrigin;
fAtlas->instantiate(rp);
return sk_ref_sp(fAtlas->priv().peekTexture());
}, GrSurfaceProxy::Renderable::kYes, kAlpha_half_GrPixelConfig);
}, GrProxyProvider::Renderable::kYes, kAlpha_half_GrPixelConfig);
fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag);
this->addTextureSampler(&fAccess);
@ -122,12 +125,13 @@ public:
private:
const char* name() const override { return "LazyProxyTest::ClipFP"; }
std::unique_ptr<GrFragmentProcessor> clone() const override {
return skstd::make_unique<ClipFP>(fTest, fAtlas);
return skstd::make_unique<ClipFP>(fProxyProvider, fTest, fAtlas);
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
GrProxyProvider* const fProxyProvider;
LazyProxyTest* const fTest;
GrTextureProxy* const fAtlas;
sk_sp<GrTextureProxy> fLazyProxy;
@ -142,9 +146,10 @@ public:
, fAtlas(atlas) {}
private:
bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
bool apply(GrContext* context, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
SkRect* bounds) const override {
out->addCoverageFP(skstd::make_unique<ClipFP>(fTest, fAtlas));
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
out->addCoverageFP(skstd::make_unique<ClipFP>(proxyProvider, fTest, fAtlas));
return true;
}
bool quickContains(const SkRect&) const final { return false; }
@ -171,6 +176,7 @@ DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderable[0] = true;
mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
for (bool nullTexture : {false, true}) {
LazyProxyTest test(reporter);
ctx->contextPriv().addOnFlushCallbackObject(&test);
@ -183,7 +189,7 @@ DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
kAlpha_half_GrPixelConfig, nullptr);
REPORTER_ASSERT(reporter, mockAtlas);
rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
skstd::make_unique<LazyProxyTest::Op>(&test, nullTexture));
skstd::make_unique<LazyProxyTest::Op>(proxyProvider, &test, nullTexture));
ctx->contextPriv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
}
}
@ -191,6 +197,7 @@ DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
GrMockOptions mockOptions;
sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
auto proxyProvider = ctx->contextPriv().proxyProvider();
GrSurfaceDesc desc;
desc.fWidth = 16;
@ -200,7 +207,7 @@ DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
for (bool doInstantiate : {true, false}) {
int testCount = 0;
int* testCountPtr = &testCount;
sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeLazy(
sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
[testCountPtr](GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
if (!resourceProvider) {
*testCountPtr = -1;