Skip to content

Commit 72c7b98

Browse files
bsalomonSkia Commit-Bot
authored andcommitted
Start removal of tool usage of SkSurface::MakeFromBackendTextureAsRenderTarget.
Adds a new helper that creates a GrBackendRenderTarget using GrGpu and then wraps it in a SkSurface. Uses the SkSurface release proc to delete the BERT using GrGpu. Upgrades GrGpu::createTestingOnlyBackendRenderTarget to create MSAA buffers. Updates many tests/tool to call sites to use the helper instead of SkSurface::MakeFromBackendTextureAsRenderTarget. Adds syncToCpu bool to SkSurface:: and GrContext::flushAndSubmit. Bug: skia:9832 Change-Id: I73a8f0ce09dc6523729af0814464c6b6657fda06 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/293683 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Jim Van Verth <jvanverth@google.com> Reviewed-by: Kevin Lubick <kjlubick@google.com>
1 parent 2e09693 commit 72c7b98

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+747
-452
lines changed

BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,8 @@ if (skia_enable_tools) {
16051605
deps = []
16061606
public_deps = []
16071607
sources = [
1608+
"tools/gpu/BackendSurfaceFactory.cpp",
1609+
"tools/gpu/BackendSurfaceFactory.h",
16081610
"tools/gpu/BackendTextureImageFactory.cpp",
16091611
"tools/gpu/BackendTextureImageFactory.h",
16101612
"tools/gpu/FlushFinishTracker.cpp",

RELEASE_NOTES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Milestone 88
99

1010
* <insert new release notes here>
1111

12+
* CPU sync bool added to SkSurface::flushAndSubmit() and GrContext::flushAndSubmit()
13+
1214
* Removed legacy variant of SkImage::MakeFromYUVAPixmaps. Use the version that
1315
takes SkYUVAPixmaps instead. It has a more structured description of the
1416
planar configuration.

dm/DMSrcSink.cpp

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "tools/DDLTileHelper.h"
5252
#include "tools/Resources.h"
5353
#include "tools/debugger/DebugCanvas.h"
54+
#include "tools/gpu/BackendSurfaceFactory.h"
5455
#include "tools/gpu/MemoryCache.h"
5556
#if defined(SK_BUILD_FOR_WIN)
5657
#include "include/docs/SkXPSDocument.h"
@@ -1467,9 +1468,9 @@ Result GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream* dstStream, SkStri
14671468
return this->onDraw(src, dst, dstStream, log, fBaseContextOptions);
14681469
}
14691470

1470-
sk_sp<SkSurface> GPUSink::createDstSurface(GrDirectContext* context, SkISize size,
1471-
GrBackendTexture* backendTexture,
1472-
GrBackendRenderTarget* backendRT) const {
1471+
sk_sp<SkSurface> GPUSink::createDstSurface(GrDirectContext* context,
1472+
SkISize size,
1473+
GrBackendTexture* backendTexture) const {
14731474
sk_sp<SkSurface> surface;
14741475

14751476
SkImageInfo info = SkImageInfo::Make(size, fColorType, fAlphaType, fColorSpace);
@@ -1490,14 +1491,13 @@ sk_sp<SkSurface> GPUSink::createDstSurface(GrDirectContext* context, SkISize siz
14901491
fColorType, info.refColorSpace(), &props);
14911492
break;
14921493
case SkCommandLineConfigGpu::SurfType::kBackendRenderTarget:
1493-
if (1 == fSampleCount) {
1494-
auto colorType = SkColorTypeToGrColorType(info.colorType());
1495-
*backendRT = context->priv().getGpu()->createTestingOnlyBackendRenderTarget(
1496-
info.width(), info.height(), colorType);
1497-
surface = SkSurface::MakeFromBackendRenderTarget(
1498-
context, *backendRT, kBottomLeft_GrSurfaceOrigin, info.colorType(),
1499-
info.refColorSpace(), &props);
1500-
}
1494+
surface = MakeBackendRenderTargetSurface(context,
1495+
info.dimensions(),
1496+
fSampleCount,
1497+
kBottomLeft_GrSurfaceOrigin,
1498+
info.colorType(),
1499+
info.refColorSpace(),
1500+
&props);
15011501
break;
15021502
}
15031503

@@ -1537,9 +1537,7 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log,
15371537
}
15381538

15391539
GrBackendTexture backendTexture;
1540-
GrBackendRenderTarget backendRT;
1541-
sk_sp<SkSurface> surface = this->createDstSurface(direct, src.size(),
1542-
&backendTexture, &backendRT);
1540+
sk_sp<SkSurface> surface = this->createDstSurface(direct, src.size(), &backendTexture);
15431541
if (!surface) {
15441542
return Result::Fatal("Could not create a surface.");
15451543
}
@@ -1570,9 +1568,6 @@ Result GPUSink::onDraw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log,
15701568
if (backendTexture.isValid()) {
15711569
direct->deleteBackendTexture(backendTexture);
15721570
}
1573-
if (backendRT.isValid()) {
1574-
direct->priv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT);
1575-
}
15761571
}
15771572
if (grOptions.fPersistentCache) {
15781573
direct->storeVkPipelineCacheData();
@@ -1749,9 +1744,7 @@ Result GPUOOPRSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* lo
17491744
SkASSERT(context->priv().getGpu());
17501745

17511746
GrBackendTexture backendTexture;
1752-
GrBackendRenderTarget backendRT;
1753-
sk_sp<SkSurface> surface = this->createDstSurface(context, src.size(),
1754-
&backendTexture, &backendRT);
1747+
sk_sp<SkSurface> surface = this->createDstSurface(context, src.size(), &backendTexture);
17551748
if (!surface) {
17561749
return Result::Fatal("Could not create a surface.");
17571750
}
@@ -1775,9 +1768,6 @@ Result GPUOOPRSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* lo
17751768
if (backendTexture.isValid()) {
17761769
context->deleteBackendTexture(backendTexture);
17771770
}
1778-
if (backendRT.isValid()) {
1779-
context->priv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT);
1780-
}
17811771

17821772
return Result::Ok();
17831773
}
@@ -1929,9 +1919,7 @@ Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log
19291919
mainTestCtx->makeCurrent();
19301920

19311921
GrBackendTexture backendTexture;
1932-
GrBackendRenderTarget backendRT;
1933-
sk_sp<SkSurface> surface = this->createDstSurface(mainCtx, src.size(),
1934-
&backendTexture, &backendRT);
1922+
sk_sp<SkSurface> surface = this->createDstSurface(mainCtx, src.size(), &backendTexture);
19351923
if (!surface) {
19361924
return Result::Fatal("Could not create a surface.");
19371925
}
@@ -1965,9 +1953,6 @@ Result GPUDDLSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log
19651953
if (backendTexture.isValid()) {
19661954
mainCtx->deleteBackendTexture(backendTexture);
19671955
}
1968-
if (backendRT.isValid()) {
1969-
mainCtx->priv().getGpu()->deleteTestingOnlyBackendRenderTarget(backendRT);
1970-
}
19711956

19721957
return Result::Ok();
19731958
}

dm/DMSrcSink.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,7 @@ class GPUSink : public Sink {
407407
}
408408

409409
protected:
410-
sk_sp<SkSurface> createDstSurface(GrDirectContext*, SkISize size, GrBackendTexture*,
411-
GrBackendRenderTarget*) const;
410+
sk_sp<SkSurface> createDstSurface(GrDirectContext*, SkISize size, GrBackendTexture*) const;
412411
bool readBack(SkSurface*, SkBitmap* dst) const;
413412

414413
private:

include/core/SkSurface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -900,9 +900,9 @@ class SK_API SkSurface : public SkRefCnt {
900900
correct ordering when the surface backing store is accessed outside Skia (e.g. direct use of
901901
the 3D API or a windowing system). GrContext has additional flush and submit methods that
902902
apply to all surfaces and images created from a GrContext. This is equivalent to calling
903-
SkSurface::flush with a default GrFlushInfo followed by GrContext::submit.
903+
SkSurface::flush with a default GrFlushInfo followed by GrContext::submit(syncCpu).
904904
*/
905-
void flushAndSubmit();
905+
void flushAndSubmit(bool syncCpu = false);
906906

907907
enum class BackendSurfaceAccess {
908908
kNoAccess, //!< back-end object will not be used by client

include/gpu/GrContext.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,11 +332,11 @@ class SK_API GrContext : public GrRecordingContext {
332332
/**
333333
* Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D
334334
* API. This is equivalent to calling GrContext::flush with a default GrFlushInfo followed by
335-
* GrContext::submit.
335+
* GrContext::submit(syncCpu).
336336
*/
337-
void flushAndSubmit() {
337+
void flushAndSubmit(bool syncCpu = false) {
338338
this->flush(GrFlushInfo());
339-
this->submit();
339+
this->submit(syncCpu);
340340
}
341341

342342
/**

modules/canvaskit/canvaskit_bindings.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1647,7 +1647,9 @@ EMSCRIPTEN_BINDINGS(Skia) {
16471647

16481648
class_<SkSurface>("SkSurface")
16491649
.smart_ptr<sk_sp<SkSurface>>("sk_sp<SkSurface>")
1650-
.function("_flush", select_overload<void()>(&SkSurface::flushAndSubmit))
1650+
.function("_flush", optional_override([](SkSurface& self) {
1651+
self.flushAndSubmit(false);
1652+
}))
16511653
.function("getCanvas", &SkSurface::getCanvas, allow_raw_pointers())
16521654
.function("imageInfo", optional_override([](SkSurface& self)->SimpleImageInfo {
16531655
const auto& ii = self.imageInfo();

src/gpu/GrGpu.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,9 +666,22 @@ class GrGpu : public SkRefCnt {
666666
/** Check a handle represents an actual texture in the backend API that has not been freed. */
667667
virtual bool isTestingOnlyBackendTexture(const GrBackendTexture&) const = 0;
668668

669-
virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h,
670-
GrColorType) = 0;
669+
/**
670+
* Creates a GrBackendRenderTarget that can be wrapped using
671+
* SkSurface::MakeFromBackendRenderTarget. Ideally this is a non-textureable allocation to
672+
* differentiate from testing with SkSurface::MakeFromBackendTexture. When sampleCnt > 1 this
673+
* is used to test client wrapped allocations with MSAA where Skia does not allocate a separate
674+
* buffer for resolving. If the color is non-null the backing store should be cleared to the
675+
* passed in color.
676+
*/
677+
virtual GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize,
678+
GrColorType,
679+
int sampleCount = 1) = 0;
671680

681+
/**
682+
* Deletes a GrBackendRenderTarget allocated with the above. Synchronization to make this safe
683+
* is up to the caller.
684+
*/
672685
virtual void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) = 0;
673686

674687
// This is only to be used in GL-specific tests.

src/gpu/GrSurfaceContext.cpp

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -207,45 +207,75 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
207207
}
208208

209209
if (readFlag == GrCaps::SurfaceReadPixelsSupport::kCopyToTexture2D || canvas2DFastPath) {
210-
GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
211-
? GrColorType::kRGBA_8888 : this->colorInfo().colorType();
212-
sk_sp<SkColorSpace> cs = canvas2DFastPath ? nullptr : this->colorInfo().refColorSpace();
213-
214-
auto tempCtx = GrRenderTargetContext::Make(
215-
dContext, colorType, std::move(cs), SkBackingFit::kApprox, dstInfo.dimensions(),
216-
1, GrMipmapped::kNo, GrProtected::kNo, kTopLeft_GrSurfaceOrigin);
217-
if (!tempCtx) {
218-
return false;
219-
}
210+
std::unique_ptr<GrSurfaceContext> tempCtx;
211+
if (this->asTextureProxy()) {
212+
GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
213+
? GrColorType::kRGBA_8888
214+
: this->colorInfo().colorType();
215+
sk_sp<SkColorSpace> cs = canvas2DFastPath ? nullptr : this->colorInfo().refColorSpace();
216+
217+
tempCtx = GrRenderTargetContext::Make(
218+
dContext, colorType, std::move(cs), SkBackingFit::kApprox, dstInfo.dimensions(),
219+
1, GrMipMapped::kNo, GrProtected::kNo, kTopLeft_GrSurfaceOrigin);
220+
if (!tempCtx) {
221+
return false;
222+
}
220223

221-
std::unique_ptr<GrFragmentProcessor> fp;
222-
if (canvas2DFastPath) {
223-
fp = dContext->priv().createPMToUPMEffect(
224-
GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType()));
225-
if (dstInfo.colorType() == GrColorType::kBGRA_8888) {
226-
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
227-
dstInfo = dstInfo.makeColorType(GrColorType::kRGBA_8888);
224+
std::unique_ptr<GrFragmentProcessor> fp;
225+
if (canvas2DFastPath) {
226+
fp = dContext->priv().createPMToUPMEffect(GrTextureEffect::Make(
227+
this->readSurfaceView(), this->colorInfo().alphaType()));
228+
if (dstInfo.colorType() == GrColorType::kBGRA_8888) {
229+
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
230+
dstInfo = dstInfo.makeColorType(GrColorType::kRGBA_8888);
231+
}
232+
// The render target context is incorrectly tagged as kPremul even though we're
233+
// writing unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type
234+
// so we don't double unpremul.
235+
dstInfo = dstInfo.makeAlphaType(kPremul_SkAlphaType);
236+
} else {
237+
fp = GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType());
238+
}
239+
if (!fp) {
240+
return false;
228241
}
229-
// The render target context is incorrectly tagged as kPremul even though we're writing
230-
// unpremul data thanks to the PMToUPM effect. Fake out the dst alpha type so we don't
231-
// double unpremul.
232-
dstInfo = dstInfo.makeAlphaType(kPremul_SkAlphaType);
242+
GrPaint paint;
243+
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
244+
paint.setColorFragmentProcessor(std::move(fp));
245+
246+
tempCtx->asRenderTargetContext()->fillRectToRect(
247+
nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
248+
SkRect::MakeWH(dstInfo.width(), dstInfo.height()),
249+
SkRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height()));
250+
pt = {0, 0};
233251
} else {
234-
fp = GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType());
235-
}
236-
if (!fp) {
237-
return false;
252+
auto restrictions = this->caps()->getDstCopyRestrictions(this->asRenderTargetProxy(),
253+
this->colorInfo().colorType());
254+
sk_sp<GrSurfaceProxy> copy;
255+
static constexpr auto kFit = SkBackingFit::kExact;
256+
static constexpr auto kBudgeted = SkBudgeted::kYes;
257+
static constexpr auto kMipMapped = GrMipMapped::kNo;
258+
if (restrictions.fMustCopyWholeSrc) {
259+
copy = GrSurfaceProxy::Copy(fContext, srcProxy, this->origin(), kMipMapped, kFit,
260+
kBudgeted);
261+
} else {
262+
auto srcRect = SkIRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height());
263+
copy = GrSurfaceProxy::Copy(fContext, srcProxy, this->origin(), kMipMapped, srcRect,
264+
kFit, kBudgeted, restrictions.fRectsMustMatch);
265+
pt = {0, 0};
266+
}
267+
if (!copy) {
268+
return false;
269+
}
270+
GrSurfaceProxyView view{std::move(copy), this->origin(), this->readSwizzle()};
271+
tempCtx = GrSurfaceContext::Make(dContext,
272+
std::move(view),
273+
this->colorInfo().colorType(),
274+
this->colorInfo().alphaType(),
275+
this->colorInfo().refColorSpace());
276+
SkASSERT(tempCtx);
238277
}
239-
GrPaint paint;
240-
paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
241-
paint.setColorFragmentProcessor(std::move(fp));
242-
243-
tempCtx->asRenderTargetContext()->fillRectToRect(
244-
nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
245-
SkRect::MakeWH(dstInfo.width(), dstInfo.height()),
246-
SkRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height()));
247-
248-
return tempCtx->readPixels(dContext, dstInfo, dst, rowBytes, {0, 0});
278+
return tempCtx->readPixels(dContext, dstInfo, dst, rowBytes, pt);
249279
}
250280

251281
bool flip = this->origin() == kBottomLeft_GrSurfaceOrigin;

src/gpu/d3d/GrD3DCaps.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,8 +911,14 @@ GrCaps::SurfaceReadPixelsSupport GrD3DCaps::surfaceSupportsReadPixels(
911911
if (GrDxgiFormatIsCompressed(tex->dxgiFormat())) {
912912
return SurfaceReadPixelsSupport::kCopyToTexture2D;
913913
}
914+
return SurfaceReadPixelsSupport::kSupported;
915+
} else if (auto rt = static_cast<const GrD3DRenderTarget*>(surface->asRenderTarget())) {
916+
if (rt->numSamples() > 1) {
917+
return SurfaceReadPixelsSupport::kCopyToTexture2D;
918+
}
919+
return SurfaceReadPixelsSupport::kSupported;
914920
}
915-
return SurfaceReadPixelsSupport::kSupported;
921+
return SurfaceReadPixelsSupport::kUnsupported;
916922
}
917923

918924
bool GrD3DCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {

0 commit comments

Comments
 (0)