(Mostly) Retract GrRenderTarget from SkGpuDevice

This gets us most of the way to having SkGpuDevice exclusively use a GrDrawContext instead of a GrRenderTarget. There are a few other refactorings (e.g., rm need for fLegacyBitmap and accessRenderTarget) before the GrRenderTarget can be completely removed.

Has calved off:
https://codereview.chromium.org/1925313002/ (Tighten up SkSpecialSurface factory functions)
https://codereview.chromium.org/1925803004/ (Add sk_sp to SkSurface_Gpu and SkGpuDevice)
https://codereview.chromium.org/1956473002/ (Retract GrRenderTarget a bit within SkGpuDevice)
https://codereview.chromium.org/1979913002/ (Rename GrDrawingMgr::abandon to wasAbandoned & add a matching entry point to GrDrawingContext)
https://codereview.chromium.org/1982583002/ (Add isUnifiedMultisampled entry point to GrDrawContext)

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1930013002

Review-Url: https://codereview.chromium.org/1930013002
This commit is contained in:
robertphillips 2016-05-17 09:57:46 -07:00 committed by Commit bot
parent cc49e5950d
commit ca6eafc0f7
7 changed files with 124 additions and 115 deletions

View File

@ -195,7 +195,6 @@ public:
/**
* Create both a GrRenderTarget and a matching GrDrawContext to wrap it.
* The created GrRenderTarget will always be budgeted.
* We guarantee that "asTexture" will succeed for drawContexts created
* via this entry point.
*/
@ -204,7 +203,8 @@ public:
GrPixelConfig config,
int sampleCnt = 0,
GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr);
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted = SkBudgeted::kYes);
///////////////////////////////////////////////////////////////////////////
// Misc.

View File

@ -261,9 +261,11 @@ public:
const GrSurfaceDesc& desc() const { return fRenderTarget->desc(); }
int width() const { return fRenderTarget->width(); }
int height() const { return fRenderTarget->height(); }
GrPixelConfig config() const { return fRenderTarget->config(); }
bool isUnifiedMultisampled() const { return fRenderTarget->isUnifiedMultisampled(); }
int numColorSamples() const { return fRenderTarget->numColorSamples(); }
bool isGammaCorrect() const { return fSurfaceProps.isGammaCorrect(); }
const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
bool wasAbandoned() const;
@ -283,8 +285,7 @@ protected:
GrDrawingManager* drawingManager() { return fDrawingManager; }
GrAuditTrail* auditTrail() { return fAuditTrail; }
const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
SkDEBUGCODE(void validate() const;)

View File

@ -115,18 +115,14 @@ sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info,
class SkSpecialSurface_Gpu : public SkSpecialSurface_Base {
public:
SkSpecialSurface_Gpu(sk_sp<GrTexture> texture,
SkSpecialSurface_Gpu(sk_sp<GrDrawContext> drawContext,
int width, int height,
const SkIRect& subset,
const SkSurfaceProps* props)
: INHERITED(subset, props)
, fTexture(std::move(texture)) {
const SkIRect& subset)
: INHERITED(subset, &drawContext->surfaceProps())
, fDrawContext(std::move(drawContext)) {
SkASSERT(fTexture->asRenderTarget());
sk_sp<SkGpuDevice> device(SkGpuDevice::Make(sk_ref_sp(fTexture->asRenderTarget()),
width, height, props,
SkGpuDevice::kUninit_InitContents));
sk_sp<SkBaseDevice> device(SkGpuDevice::Make(fDrawContext, width, height,
SkGpuDevice::kUninit_InitContents));
if (!device) {
return;
}
@ -141,15 +137,16 @@ public:
~SkSpecialSurface_Gpu() override { }
sk_sp<SkSpecialImage> onMakeImageSnapshot() override {
// Note: we are intentionally zeroing out 'fTexture' here
return SkSpecialImage::MakeFromGpu(this->subset(),
kNeedNewImageUniqueID_SpecialImage,
std::move(fTexture),
&this->props());
sk_sp<SkSpecialImage> tmp(SkSpecialImage::MakeFromGpu(this->subset(),
kNeedNewImageUniqueID_SpecialImage,
fDrawContext->asTexture(),
&this->props()));
fDrawContext = nullptr;
return tmp;
}
private:
sk_sp<GrTexture> fTexture;
sk_sp<GrDrawContext> fDrawContext;
typedef SkSpecialSurface_Base INHERITED;
};
@ -161,20 +158,15 @@ sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrContext* context,
return nullptr;
}
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = width;
desc.fHeight = height;
desc.fConfig = config;
sk_sp<GrTexture> tex(context->textureProvider()->createApproxTexture(desc));
if (!tex) {
sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
width, height, config));
if (!drawContext) {
return nullptr;
}
const SkIRect subset = SkIRect::MakeWH(width, height);
return sk_make_sp<SkSpecialSurface_Gpu>(std::move(tex), width, height, subset, nullptr);
return sk_make_sp<SkSpecialSurface_Gpu>(std::move(drawContext), width, height, subset);
}
#endif

View File

@ -656,7 +656,8 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
GrPixelConfig config,
int sampleCnt,
GrSurfaceOrigin origin,
const SkSurfaceProps* surfaceProps) {
const SkSurfaceProps* surfaceProps,
SkBudgeted budgeted) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fOrigin = origin;
@ -667,7 +668,7 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
sk_sp<GrTexture> tex;
if (SkBackingFit::kExact == fit) {
tex.reset(this->textureProvider()->createTexture(desc, SkBudgeted::kYes));
tex.reset(this->textureProvider()->createTexture(desc, budgeted));
} else {
tex.reset(this->textureProvider()->createApproxTexture(desc));
}

View File

@ -129,21 +129,34 @@ bool SkGpuDevice::CheckAlphaTypeAndGetFlags(
sk_sp<SkGpuDevice> SkGpuDevice::Make(sk_sp<GrRenderTarget> rt, const SkSurfaceProps* props,
InitContents init) {
const int width = rt->width();
const int height = rt->height();
return SkGpuDevice::Make(std::move(rt), width, height, props, init);
}
sk_sp<SkGpuDevice> SkGpuDevice::Make(sk_sp<GrRenderTarget> rt, int width, int height,
const SkSurfaceProps* props, InitContents init) {
if (!rt || rt->wasDestroyed()) {
if (!rt || rt->wasDestroyed() || !rt->getContext()) {
return nullptr;
}
unsigned flags;
if (!CheckAlphaTypeAndGetFlags(nullptr, init, &flags)) {
return nullptr;
}
return sk_sp<SkGpuDevice>(new SkGpuDevice(rt.get(), width, height, props, flags));
const int width = rt->width();
const int height = rt->height();
GrContext* context = rt->getContext();
sk_sp<GrDrawContext> drawContext(context->drawContext(std::move(rt), props));
return sk_sp<SkGpuDevice>(new SkGpuDevice(std::move(drawContext), width, height, flags));
}
sk_sp<SkBaseDevice> SkGpuDevice::Make(sk_sp<GrDrawContext> drawContext,
int width, int height,
InitContents init) {
if (!drawContext || drawContext->wasAbandoned()) {
return nullptr;
}
unsigned flags;
if (!CheckAlphaTypeAndGetFlags(nullptr, init, &flags)) {
return nullptr;
}
return sk_sp<SkBaseDevice>(new SkGpuDevice(std::move(drawContext), width, height, flags));
}
sk_sp<SkGpuDevice> SkGpuDevice::Make(GrContext* context, SkBudgeted budgeted,
@ -154,35 +167,39 @@ sk_sp<SkGpuDevice> SkGpuDevice::Make(GrContext* context, SkBudgeted budgeted,
return nullptr;
}
SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
if (!rt) {
sk_sp<GrDrawContext> drawContext(CreateDrawContext(context, budgeted, info,
sampleCount, props));
if (!drawContext) {
return nullptr;
}
return sk_sp<SkGpuDevice>(new SkGpuDevice(rt, info.width(), info.height(), props, flags));
return sk_sp<SkGpuDevice>(new SkGpuDevice(std::move(drawContext),
info.width(), info.height(), flags));
}
SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, int width, int height,
const SkSurfaceProps* props, unsigned flags)
: INHERITED(SkSurfacePropsCopyOrDefault(props))
, fContext(SkRef(rt->getContext()))
, fRenderTarget(SkRef(rt)) {
SkGpuDevice::SkGpuDevice(sk_sp<GrDrawContext> drawContext, int width, int height, unsigned flags)
: INHERITED(drawContext->surfaceProps())
, fContext(SkRef(drawContext->accessRenderTarget()->getContext()))
, fRenderTarget(drawContext->renderTarget())
, fDrawContext(std::move(drawContext)) {
fOpaque = SkToBool(flags & kIsOpaque_Flag);
SkAlphaType at = fOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
SkImageInfo info = rt->surfacePriv().info(at).makeWH(width, height);
SkPixelRef* pr = new SkGrPixelRef(info, rt);
SkImageInfo info = fRenderTarget->surfacePriv().info(at).makeWH(width, height);
SkPixelRef* pr = new SkGrPixelRef(info, fRenderTarget.get());
fLegacyBitmap.setInfo(info);
fLegacyBitmap.setPixelRef(pr)->unref();
fDrawContext = this->context()->drawContext(sk_ref_sp(rt), &this->surfaceProps());
if (flags & kNeedClear_Flag) {
this->clearAll();
}
}
GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkBudgeted budgeted,
const SkImageInfo& origInfo, int sampleCount) {
sk_sp<GrDrawContext> SkGpuDevice::CreateDrawContext(GrContext* context,
SkBudgeted budgeted,
const SkImageInfo& origInfo,
int sampleCount,
const SkSurfaceProps* surfaceProps) {
if (kUnknown_SkColorType == origInfo.colorType() ||
origInfo.width() < 0 || origInfo.height() < 0) {
return nullptr;
@ -208,21 +225,13 @@ GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkBudgeted b
ct = kN32_SkColorType;
}
const SkImageInfo info = SkImageInfo::Make(origInfo.width(), origInfo.height(), ct, at, pt);
GrPixelConfig config = SkImageInfo2GrPixelConfig(ct, at, pt, *context->caps());
return context->newDrawContext(SkBackingFit::kExact, // Why exact?
origInfo.width(), origInfo.height(),
config, sampleCount,
kDefault_GrSurfaceOrigin, surfaceProps, budgeted);
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = info.width();
desc.fHeight = info.height();
desc.fConfig = SkImageInfo2GrPixelConfig(info, *context->caps());
desc.fSampleCnt = sampleCount;
desc.fIsMipMapped = false;
GrTexture* texture = context->textureProvider()->createTexture(desc, budgeted, nullptr, 0);
if (nullptr == texture) {
return nullptr;
}
SkASSERT(nullptr != texture->asRenderTarget());
return texture->asRenderTarget();
}
// This method ensures that we always have a texture-backed "bitmap" when we finally
@ -346,7 +355,7 @@ void SkGpuDevice::prepareDraw(const SkDraw& draw) {
GrRenderTarget* SkGpuDevice::accessRenderTarget() {
ASSERT_SINGLE_OWNER
return fRenderTarget;
return fRenderTarget.get();
}
GrDrawContext* SkGpuDevice::accessDrawContext() {
@ -362,15 +371,17 @@ void SkGpuDevice::clearAll() {
fDrawContext->clear(&rect, color, true);
}
void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
void SkGpuDevice::replaceDrawContext(bool shouldRetainContent) {
ASSERT_SINGLE_OWNER
SkBudgeted budgeted = fRenderTarget->resourcePriv().isBudgeted();
SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget(
this->context(), budgeted, this->imageInfo(), fRenderTarget->desc().fSampleCnt));
if (nullptr == newRT) {
sk_sp<GrDrawContext> newDC(CreateDrawContext(this->context(),
budgeted,
this->imageInfo(),
fDrawContext->numColorSamples(),
&this->surfaceProps()));
if (!newDC) {
return;
}
@ -378,23 +389,24 @@ void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
if (fRenderTarget->wasDestroyed()) {
return;
}
this->context()->copySurface(newRT, fRenderTarget);
newDC->copySurface(fDrawContext->asTexture().get(),
SkIRect::MakeWH(this->width(), this->height()),
SkIPoint::Make(0, 0));
}
SkASSERT(fRenderTarget != newRT);
SkASSERT(fDrawContext->accessRenderTarget() != newDC->accessRenderTarget());
fRenderTarget.reset(newRT.release());
fRenderTarget = newDC->renderTarget();
#ifdef SK_DEBUG
SkImageInfo info = fRenderTarget->surfacePriv().info(fOpaque ? kOpaque_SkAlphaType :
kPremul_SkAlphaType);
SkASSERT(info == fLegacyBitmap.info());
#endif
SkPixelRef* pr = new SkGrPixelRef(fLegacyBitmap.info(), fRenderTarget);
SkPixelRef* pr = new SkGrPixelRef(fLegacyBitmap.info(), fRenderTarget.get());
fLegacyBitmap.setPixelRef(pr)->unref();
fDrawContext = this->context()->drawContext(sk_ref_sp(fRenderTarget.get()),
&this->surfaceProps());
fDrawContext = newDC;
}
///////////////////////////////////////////////////////////////////////////////
@ -1319,9 +1331,8 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
// drawDevice is defined to be in device coords.
CHECK_SHOULD_DRAW(draw);
GrRenderTarget* devRT = dev->accessRenderTarget();
GrTexture* devTex;
if (nullptr == (devTex = devRT->asTexture())) {
sk_sp<GrTexture> devTex(dev->accessDrawContext()->asTexture());
if (!devTex) {
return;
}
@ -1333,7 +1344,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
GrPaint grPaint;
SkAutoTUnref<const GrFragmentProcessor> fp(
GrSimpleTextureEffect::Create(devTex, SkMatrix::I()));
GrSimpleTextureEffect::Create(devTex.get(), SkMatrix::I()));
if (GrPixelConfigIsAlphaOnly(devTex->config())) {
// Can this happen?
fp.reset(GrFragmentProcessor::MulOutputByInputUnpremulColor(fp));
@ -1735,36 +1746,33 @@ void SkGpuDevice::flush() {
SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
ASSERT_SINGLE_OWNER
GrSurfaceDesc desc;
desc.fConfig = fRenderTarget->config();
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = cinfo.fInfo.width();
desc.fHeight = cinfo.fInfo.height();
desc.fSampleCnt = fRenderTarget->desc().fSampleCnt;
SkAutoTUnref<GrTexture> texture;
// Skia's convention is to only clear a device if it is non-opaque.
InitContents init = cinfo.fInfo.isOpaque() ? kUninit_InitContents : kClear_InitContents;
SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry);
// layers are never draw in repeat modes, so we can request an approx
// layers are never drawn in repeat modes, so we can request an approx
// match and ignore any padding.
if (kNever_TileUsage == cinfo.fTileUsage) {
texture.reset(fContext->textureProvider()->createApproxTexture(desc));
} else {
texture.reset(fContext->textureProvider()->createTexture(desc, SkBudgeted::kYes));
}
SkBackingFit fit = kNever_TileUsage == cinfo.fTileUsage ? SkBackingFit::kApprox
: SkBackingFit::kExact;
if (texture) {
SkSurfaceProps props(this->surfaceProps().flags(), cinfo.fPixelGeometry);
return SkGpuDevice::Make(sk_ref_sp(texture->asRenderTarget()),
cinfo.fInfo.width(), cinfo.fInfo.height(),
&props, init).release();
} else {
sk_sp<GrDrawContext> dc(fContext->newDrawContext(fit,
cinfo.fInfo.width(), cinfo.fInfo.height(),
fDrawContext->config(),
fDrawContext->desc().fSampleCnt,
kDefault_GrSurfaceOrigin,
&props));
if (!dc) {
SkErrorInternals::SetError( kInternalError_SkError,
"---- failed to create gpu device texture [%d %d]\n",
cinfo.fInfo.width(), cinfo.fInfo.height());
return nullptr;
return nullptr;
}
// Skia's convention is to only clear a device if it is non-opaque.
InitContents init = cinfo.fInfo.isOpaque() ? kUninit_InitContents : kClear_InitContents;
return SkGpuDevice::Make(std::move(dc),
cinfo.fInfo.width(), cinfo.fInfo.height(),
init).release();
}
sk_sp<SkSurface> SkGpuDevice::makeSurface(const SkImageInfo& info, const SkSurfaceProps& props) {

View File

@ -36,17 +36,21 @@ public:
/**
* Creates an SkGpuDevice from a GrRenderTarget.
* TODO: rm this factory. It is used by SkSurface::MakeRenderTargetDirect,
* MakeFromBackendTexture, MakeFromBackendRenderTarget,
* and MakeFromBackendTextureAsRenderTarget. Only the first is worrisome.
*/
static sk_sp<SkGpuDevice> Make(sk_sp<GrRenderTarget> target,
const SkSurfaceProps*,
InitContents);
/**
* Creates an SkGpuDevice from a GrRenderTarget whose texture width/height is
* Creates an SkGpuDevice from a GrDrawContext whose backing width/height is
* different than its actual width/height (e.g., approx-match scratch texture).
*/
static sk_sp<SkGpuDevice> Make(sk_sp<GrRenderTarget> target, int width, int height,
const SkSurfaceProps*, InitContents);
static sk_sp<SkBaseDevice> Make(sk_sp<GrDrawContext> drawContext,
int width, int height,
InitContents);
/**
* New device that will create an offscreen renderTarget based on the ImageInfo and
@ -70,7 +74,7 @@ public:
// set all pixels to 0
void clearAll();
void replaceRenderTarget(bool shouldRetainContent);
void replaceDrawContext(bool shouldRetainContent);
GrRenderTarget* accessRenderTarget() override;
GrDrawContext* accessDrawContext() override;
@ -148,7 +152,7 @@ protected:
private:
// We want these unreffed in DrawContext, RenderTarget, GrContext order.
SkAutoTUnref<GrContext> fContext;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
sk_sp<GrRenderTarget> fRenderTarget;
sk_sp<GrDrawContext> fDrawContext;
SkAutoTUnref<const SkClipStack> fClipStack;
@ -166,7 +170,7 @@ private:
static bool CheckAlphaTypeAndGetFlags(const SkImageInfo* info, InitContents init,
unsigned* flags);
SkGpuDevice(GrRenderTarget*, int width, int height, const SkSurfaceProps*, unsigned flags);
SkGpuDevice(sk_sp<GrDrawContext>, int width, int height, unsigned flags);
SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override;
@ -249,8 +253,11 @@ private:
bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);
static GrRenderTarget* CreateRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
int sampleCount);
static sk_sp<GrDrawContext> CreateDrawContext(GrContext*,
SkBudgeted,
const SkImageInfo&,
int sampleCount,
const SkSurfaceProps*);
void drawSpriteWithFilter(const SkDraw&, const SkBitmap&, int x, int y,
const SkPaint&) override;

View File

@ -115,7 +115,7 @@ void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
sk_sp<SkImage> image(this->refCachedImage(SkBudgeted::kNo, kNo_ForceUnique));
SkASSERT(image);
if (rt->asTexture() == as_IB(image)->peekTexture()) {
this->fDevice->replaceRenderTarget(SkSurface::kRetain_ContentChangeMode == mode);
this->fDevice->replaceDrawContext(SkSurface::kRetain_ContentChangeMode == mode);
SkTextureImageApplyBudgetedDecision(image.get());
} else if (kDiscard_ContentChangeMode == mode) {
this->SkSurface_Gpu::onDiscard();
@ -123,7 +123,7 @@ void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) {
}
void SkSurface_Gpu::onDiscard() {
fDevice->accessRenderTarget()->discard();
fDevice->accessDrawContext()->discard();
}
void SkSurface_Gpu::onPrepareForExternalIO() {