Have GrTextureOp use GrSurfaceProxyViews instead of just proxys.
Additionally updated some calls upstack to pass in the views.
Bug: skia:9556
Change-Id: I2b6274cb1811b102713433d51a9b18d47778174a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/251759
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a6ba1ea..a6141c6 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -610,7 +610,7 @@
}
void GrRenderTargetContext::drawTexturedQuad(const GrClip& clip,
- sk_sp<GrTextureProxy> proxy,
+ GrSurfaceProxyView proxyView,
GrColorType srcColorType,
sk_sp<GrColorSpaceXform> textureXform,
GrSamplerState::Filter filter,
@@ -624,7 +624,7 @@
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
- SkASSERT(proxy);
+ SkASSERT(proxyView.asTextureProxy());
GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContext", "drawTexturedQuad", fContext);
AutoCheckFlush acf(this->drawingManager());
@@ -648,7 +648,7 @@
// Use the provided domain, although hypothetically we could detect that the cropped local
// quad is sufficiently inside the domain and the constraint could be dropped.
this->addDrawOp(finalClip,
- GrTextureOp::Make(fContext, std::move(proxy), srcColorType,
+ GrTextureOp::Make(fContext, std::move(proxyView), srcColorType,
std::move(textureXform), filter, color, saturate,
blendMode, aaType, edgeFlags, croppedDeviceQuad,
croppedLocalQuad, domain));
@@ -898,9 +898,9 @@
const SkRect* domain = constraint == SkCanvas::kStrict_SrcRectConstraint
? &set[i].fSrcRect : nullptr;
- this->drawTexturedQuad(clip, set[i].fProxy, set[i].fSrcColorType, texXform, filter,
- {alpha, alpha, alpha, alpha}, mode, aa, set[i].fAAFlags,
- quad, srcQuad, domain);
+ this->drawTexturedQuad(clip, set[i].fProxyView, set[i].fSrcColorType, texXform, filter,
+ {alpha, alpha, alpha, alpha}, mode, aa, set[i].fAAFlags, quad,
+ srcQuad, domain);
}
} else {
// Can use a single op, avoiding GrPaint creation, and can batch across proxies
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 286bff5..19d240a 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -202,9 +202,12 @@
sk_sp<GrColorSpaceXform> texXform) {
const SkRect* domain = constraint == SkCanvas::kStrict_SrcRectConstraint ?
&srcRect : nullptr;
- this->drawTexturedQuad(clip, std::move(proxy), srcColorType, std::move(texXform), filter,
- color, mode, aa, edgeAA, GrQuad::MakeFromRect(dstRect, viewMatrix),
- GrQuad(srcRect), domain);
+ GrSurfaceOrigin origin = proxy->origin();
+ const GrSwizzle& swizzle = proxy->textureSwizzle();
+ GrSurfaceProxyView proxyView(std::move(proxy), origin, swizzle);
+ this->drawTexturedQuad(clip, std::move(proxyView), srcColorType, std::move(texXform),
+ filter, color, mode, aa, edgeAA,
+ GrQuad::MakeFromRect(dstRect, viewMatrix), GrQuad(srcRect), domain);
}
/**
@@ -218,14 +221,18 @@
const SkPoint srcQuad[4], const SkPoint dstQuad[4], GrAA aa,
GrQuadAAFlags edgeAA, const SkRect* domain, const SkMatrix& viewMatrix,
sk_sp<GrColorSpaceXform> texXform) {
- this->drawTexturedQuad(clip, std::move(proxy), srcColorType, std::move(texXform), filter,
- color, mode, aa, edgeAA, GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
+ GrSurfaceOrigin origin = proxy->origin();
+ const GrSwizzle& swizzle = proxy->textureSwizzle();
+ GrSurfaceProxyView proxyView(std::move(proxy), origin, swizzle);
+ this->drawTexturedQuad(clip, std::move(proxyView), srcColorType, std::move(texXform),
+ filter, color, mode, aa, edgeAA,
+ GrQuad::MakeFromSkQuad(dstQuad, viewMatrix),
GrQuad::MakeFromSkQuad(srcQuad, SkMatrix::I()), domain);
}
/** Used with drawTextureSet */
struct TextureSetEntry {
- sk_sp<GrTextureProxy> fProxy;
+ GrSurfaceProxyView fProxyView;
GrColorType fSrcColorType;
SkRect fSrcRect;
SkRect fDstRect;
@@ -601,7 +608,7 @@
// Like drawFilledQuad but does not require using a GrPaint or FP for texturing
void drawTexturedQuad(const GrClip& clip,
- sk_sp<GrTextureProxy> proxy,
+ GrSurfaceProxyView proxyView,
GrColorType srcColorType,
sk_sp<GrColorSpaceXform> textureXform,
GrSamplerState::Filter filter,
diff --git a/src/gpu/GrSurfaceProxyView.h b/src/gpu/GrSurfaceProxyView.h
index 1649e12..419c117 100644
--- a/src/gpu/GrSurfaceProxyView.h
+++ b/src/gpu/GrSurfaceProxyView.h
@@ -25,16 +25,16 @@
: fProxy(proxy), fOrigin(kTopLeft_GrSurfaceOrigin) {}
GrSurfaceProxyView(GrSurfaceProxyView&& view) = default;
- GrSurfaceProxyView(const GrSurfaceProxyView&) = delete;
+ GrSurfaceProxyView(const GrSurfaceProxyView&) = default;
- GrSurfaceProxyView& operator=(const GrSurfaceProxyView& that) = default;
+ GrSurfaceProxyView& operator=(const GrSurfaceProxyView&) = default;
- bool operator==(const GrSurfaceProxyView& view) {
- return fProxy.get() == view.fProxy.get() &&
+ bool operator==(const GrSurfaceProxyView& view) const {
+ return fProxy->uniqueID() == view.fProxy->uniqueID() &&
fOrigin == view.fOrigin &&
fSwizzle == view.fSwizzle;
}
- bool operator!=(const GrSurfaceProxyView& other) { return !(*this == other); }
+ bool operator!=(const GrSurfaceProxyView& other) const { return !(*this == other); }
GrSurfaceProxy* proxy() const { return fProxy.get(); }
GrTextureProxy* asTextureProxy() const { return fProxy->asTextureProxy(); }
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 1179a8f..ce5c49b 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -551,7 +551,10 @@
continue;
}
- textures[i].fProxy = std::move(proxy);
+ // TODO: have refPinnedTextureProxy and asTextureProxyRef return GrSurfaceProxyViews.
+ GrSurfaceOrigin origin = proxy->origin();
+ const GrSwizzle& swizzle = proxy->textureSwizzle();
+ textures[i].fProxyView = {std::move(proxy), origin, swizzle};
textures[i].fSrcColorType = SkColorTypeToGrColorType(image->colorType());
textures[i].fSrcRect = set[i].fSrcRect;
textures[i].fDstRect = set[i].fDstRect;
@@ -562,8 +565,9 @@
textures[i].fAAFlags = SkToGrQuadAAFlags(set[i].fAAFlags);
if (n > 0 &&
- (!GrTextureProxy::ProxiesAreCompatibleAsDynamicState(textures[i].fProxy.get(),
- textures[base].fProxy.get()) ||
+ (!GrTextureProxy::ProxiesAreCompatibleAsDynamicState(
+ textures[i].fProxyView.asTextureProxy(),
+ textures[base].fProxyView.asTextureProxy()) ||
set[i].fImage->alphaType() != set[base].fImage->alphaType() ||
!SkColorSpace::Equals(set[i].fImage->colorSpace(), set[base].fImage->colorSpace()))) {
draw();
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index e4a287c..7f5c593 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -144,7 +144,7 @@
class TextureOp final : public GrMeshDrawOp {
public:
static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
- sk_sp<GrTextureProxy> proxy,
+ GrSurfaceProxyView proxyView,
sk_sp<GrColorSpaceXform> textureXform,
GrSamplerState::Filter filter,
const SkPMColor4f& color,
@@ -155,8 +155,9 @@
const GrQuad& localQuad,
const SkRect* domain) {
GrOpMemoryPool* pool = context->priv().opMemoryPool();
- return pool->allocate<TextureOp>(std::move(proxy), std::move(textureXform), filter, color,
- saturate, aaType, aaFlags, deviceQuad, localQuad, domain);
+ return pool->allocate<TextureOp>(std::move(proxyView), std::move(textureXform), filter,
+ color, saturate, aaType, aaFlags, deviceQuad, localQuad,
+ domain);
}
static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
const GrRenderTargetContext::TextureSetEntry set[],
@@ -167,7 +168,7 @@
SkCanvas::SrcRectConstraint constraint,
const SkMatrix& viewMatrix,
sk_sp<GrColorSpaceXform> textureColorSpaceXform) {
- size_t size = sizeof(TextureOp) + sizeof(ProxyCountPair) * (cnt - 1);
+ size_t size = sizeof(TextureOp) + sizeof(ViewCountPair) * (cnt - 1);
GrOpMemoryPool* pool = context->priv().opMemoryPool();
void* mem = pool->allocate(size);
return std::unique_ptr<GrDrawOp>(new (mem) TextureOp(set, cnt, filter, saturate, aaType,
@@ -176,8 +177,8 @@
}
~TextureOp() override {
- for (unsigned p = 0; p < fProxyCnt; ++p) {
- fProxyCountPairs[p].fProxy->unref();
+ for (unsigned p = 1; p < fProxyCnt; ++p) {
+ fViewCountPairs[p].~ViewCountPair();
}
}
@@ -186,7 +187,7 @@
void visitProxies(const VisitProxyFunc& func) const override {
for (unsigned p = 0; p < fProxyCnt; ++p) {
bool mipped = (GrSamplerState::Filter::kMipMap == this->filter());
- func(fProxyCountPairs[p].fProxy, GrMipMapped(mipped));
+ func(fViewCountPairs[p].fProxyView.asTextureProxy(), GrMipMapped(mipped));
}
}
@@ -197,10 +198,10 @@
auto iter = fQuads.iterator();
for (unsigned p = 0; p < fProxyCnt; ++p) {
str.appendf("Proxy ID: %d, Filter: %d\n",
- fProxyCountPairs[p].fProxy->uniqueID().asUInt(),
+ fViewCountPairs[p].fProxyView.proxy()->uniqueID().asUInt(),
static_cast<int>(fFilter));
int i = 0;
- while(i < fProxyCountPairs[p].fQuadCnt && iter.next()) {
+ while(i < fViewCountPairs[p].fQuadCnt && iter.next()) {
const GrQuad& quad = iter.deviceQuad();
const GrQuad& uv = iter.localQuad();
const ColorDomainAndAA& info = iter.metadata();
@@ -262,8 +263,8 @@
Domain domain() const { return Domain(fHasDomain); }
GrQuadAAFlags aaFlags() const { return static_cast<GrQuadAAFlags>(fAAFlags); }
};
- struct ProxyCountPair {
- GrTextureProxy* fProxy;
+ struct ViewCountPair {
+ GrSurfaceProxyView fProxyView;
int fQuadCnt;
};
@@ -336,7 +337,7 @@
// dstQuad should be the geometry transformed by the view matrix. If domainRect
// is not null it will be used to apply the strict src rect constraint.
- TextureOp(sk_sp<GrTextureProxy> proxy,
+ TextureOp(GrSurfaceProxyView proxyView,
sk_sp<GrColorSpaceXform> textureColorSpaceXform,
GrSamplerState::Filter filter,
const SkPMColor4f& color,
@@ -358,7 +359,8 @@
fAAType = static_cast<unsigned>(aaType);
// We expect our caller to have already caught this optimization.
- SkASSERT(!domainRect || !domainRect->contains(proxy->backingStoreBoundsRect()));
+ SkASSERT(!domainRect ||
+ !domainRect->contains(proxyView.proxy()->backingStoreBoundsRect()));
// We may have had a strict constraint with nearest filter solely due to possible AA bloat.
// If we don't have (or determined we don't need) coverage AA then we can skip using a
@@ -371,7 +373,7 @@
fQuads.append(dstQuad, {color, domainRect, aaFlags}, &srcQuad);
fProxyCnt = 1;
- fProxyCountPairs[0] = {proxy.release(), 1};
+ fViewCountPairs[0] = {std::move(proxyView), 1};
fTotNumQuads = 1;
this->setBounds(dstQuad.bounds(), HasAABloat(aaType == GrAAType::kCoverage),
IsHairline::kNo);
@@ -399,12 +401,23 @@
bool allOpaque = true;
Domain netDomain = Domain::kNo;
GrTextureProxy* curProxy = nullptr;
+
for (unsigned p = 0; p < fProxyCnt; ++p) {
- fProxyCountPairs[p].fProxy = curProxy = SkRef(set[p].fProxy.get());
- fProxyCountPairs[p].fQuadCnt = 1;
+ if (p == 0) {
+ // We do not placement new the first ViewCountPair since that one is allocated and
+ // initialized as part of the GrTextureOp creation.
+ fViewCountPairs[p].fProxyView = std::move(set[p].fProxyView);
+ fViewCountPairs[p].fQuadCnt = 1;
+ } else {
+ // We must placement new the ViewCountPairs here so that the sk_sps in the
+ // GrSurfaceProxyView get initialized properly.
+ new(&fViewCountPairs[p])ViewCountPair({std::move(set[p].fProxyView), 1});
+ }
fTotNumQuads += 1;
- SkASSERT(curProxy->textureType() == fProxyCountPairs[0].fProxy->textureType());
- SkASSERT(curProxy->config() == fProxyCountPairs[0].fProxy->config());
+ curProxy = fViewCountPairs[p].fProxyView.asTextureProxy();
+ SkASSERT(curProxy->textureType() ==
+ fViewCountPairs[0].fProxyView.asTextureProxy()->textureType());
+ SkASSERT(curProxy->config() == fViewCountPairs[0].fProxyView.proxy()->config());
SkMatrix ctm = viewMatrix;
if (set[p].fPreViewMatrix) {
@@ -536,9 +549,9 @@
for (const auto& op : ChainRange<TextureOp>(texOp)) {
auto iter = op.fQuads.iterator();
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
- GrTextureProxy* proxy = op.fProxyCountPairs[p].fProxy;
+ GrTextureProxy* proxy = op.fViewCountPairs[p].fProxyView.asTextureProxy();
- int quadCnt = op.fProxyCountPairs[p].fQuadCnt;
+ int quadCnt = op.fViewCountPairs[p].fQuadCnt;
SkDEBUGCODE(totQuadsSeen += quadCnt;)
int meshVertexCnt = quadCnt * desc->fVertexSpec.verticesPerQuad();
@@ -583,16 +596,16 @@
#ifdef SK_DEBUG
void validate() const override {
- auto textureType = fProxyCountPairs[0].fProxy->textureType();
- const GrSwizzle& swizzle = fProxyCountPairs[0].fProxy->textureSwizzle();
+ auto textureType = fViewCountPairs[0].fProxyView.asTextureProxy()->textureType();
GrAAType aaType = this->aaType();
for (const auto& op : ChainRange<TextureOp>(this)) {
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
- auto* proxy = op.fProxyCountPairs[p].fProxy;
+ auto* proxy = op.fViewCountPairs[p].fProxyView.asTextureProxy();
SkASSERT(proxy);
SkASSERT(proxy->textureType() == textureType);
- SkASSERT(proxy->textureSwizzle() == swizzle);
+ SkASSERT(op.fViewCountPairs[p].fProxyView.swizzle() ==
+ fViewCountPairs[0].fProxyView.swizzle());
}
// Each individual op must be a single aaType. kCoverage and kNone ops can chain
@@ -631,7 +644,7 @@
desc->fNumProxies += op.fProxyCnt;
for (unsigned p = 0; p < op.fProxyCnt; ++p) {
- maxQuadsPerMesh = SkTMax(op.fProxyCountPairs[p].fQuadCnt, maxQuadsPerMesh);
+ maxQuadsPerMesh = SkTMax(op.fViewCountPairs[p].fQuadCnt, maxQuadsPerMesh);
}
desc->fNumTotalQuads += op.totNumQuads();
@@ -656,7 +669,7 @@
#ifdef SK_DEBUG
int tmp = 0;
for (unsigned p = 0; p < fProxyCnt; ++p) {
- tmp += fProxyCountPairs[p].fQuadCnt;
+ tmp += fViewCountPairs[p].fQuadCnt;
}
SkASSERT(tmp == fTotNumQuads);
#endif
@@ -732,8 +745,9 @@
sk_sp<GrGeometryProcessor> gp;
{
- const GrBackendFormat& backendFormat = fProxyCountPairs[0].fProxy->backendFormat();
- const GrSwizzle& swizzle = fProxyCountPairs[0].fProxy->textureSwizzle();
+ const GrBackendFormat& backendFormat =
+ fViewCountPairs[0].fProxyView.proxy()->backendFormat();
+ const GrSwizzle& swizzle = fViewCountPairs[0].fProxyView.swizzle();
GrSamplerState samplerState = GrSamplerState(GrSamplerState::WrapMode::kClamp,
this->filter());
@@ -804,13 +818,16 @@
if (fFilter != that->fFilter) {
return CombineResult::kCannotCombine;
}
- auto thisProxy = fProxyCountPairs[0].fProxy;
- auto thatProxy = that->fProxyCountPairs[0].fProxy;
- if (fProxyCnt > 1 || that->fProxyCnt > 1 ||
- thisProxy->uniqueID() != thatProxy->uniqueID()) {
+ const auto& thisView = fViewCountPairs[0].fProxyView;
+ const auto& thatView = that->fViewCountPairs[0].fProxyView;
+ auto thisProxy = thisView.asTextureProxy();
+ auto thatProxy = thatView.asTextureProxy();
+ if (fProxyCnt > 1 || that->fProxyCnt > 1 || thisView != thatView) {
// We can't merge across different proxies. Check if 'this' can be chained with 'that'.
if (GrTextureProxy::ProxiesAreCompatibleAsDynamicState(thisProxy, thatProxy) &&
- caps.dynamicStateArrayGeometryProcessorTextureSupport()) {
+ caps.dynamicStateArrayGeometryProcessorTextureSupport() &&
+ thisView.swizzle() == thatView.swizzle() &&
+ thisView.origin() == thatView.origin()) {
return CombineResult::kMayChain;
}
return CombineResult::kCannotCombine;
@@ -824,7 +841,7 @@
// Concatenate quad lists together
fQuads.concat(that->fQuads);
- fProxyCountPairs[0].fQuadCnt += that->fQuads.count();
+ fViewCountPairs[0].fQuadCnt += that->fQuads.count();
fTotNumQuads += that->fQuads.count();
return CombineResult::kMerged;
@@ -849,9 +866,9 @@
unsigned fProxyCnt : 32 - 8;
// This field must go last. When allocating this op, we will allocate extra space to hold
- // additional ProxyCountPairs immediately after the op's allocation so we can treat this
+ // additional ViewCountPairs immediately after the op's allocation so we can treat this
// as an fProxyCnt-length array.
- ProxyCountPair fProxyCountPairs[1];
+ ViewCountPair fViewCountPairs[1];
static_assert(GrQuad::kTypeCount <= 4, "GrQuad::Type does not fit in 2 bits");
@@ -863,7 +880,7 @@
namespace GrTextureOp {
std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
- sk_sp<GrTextureProxy> proxy,
+ GrSurfaceProxyView proxyView,
GrColorType srcColorType,
sk_sp<GrColorSpaceXform> textureXform,
GrSamplerState::Filter filter,
@@ -875,6 +892,7 @@
const GrQuad& deviceQuad,
const GrQuad& localQuad,
const SkRect* domain) {
+ GrTextureProxy* proxy = proxyView.asTextureProxy();
// Apply optimizations that are valid whether or not using GrTextureOp or GrFillRectOp
if (domain && domain->contains(proxy->backingStoreBoundsRect())) {
// No need for a shader-based domain if hardware clamping achieves the same effect
@@ -886,8 +904,8 @@
}
if (blendMode == SkBlendMode::kSrcOver) {
- return TextureOp::Make(context, std::move(proxy), std::move(textureXform), filter, color,
- saturate, aaType, aaFlags, deviceQuad, localQuad, domain);
+ return TextureOp::Make(context, std::move(proxyView), std::move(textureXform), filter,
+ color, saturate, aaType, aaFlags, deviceQuad, localQuad, domain);
} else {
// Emulate complex blending using GrFillRectOp
GrPaint paint;
@@ -902,10 +920,10 @@
SkRect correctedDomain;
compute_domain(Domain::kYes, filter, kTopLeft_GrSurfaceOrigin, *domain,
1.f, 1.f, proxy->height(), &correctedDomain);
- fp = GrTextureDomainEffect::Make(std::move(proxy), srcColorType, SkMatrix::I(),
+ fp = GrTextureDomainEffect::Make(sk_ref_sp(proxy), srcColorType, SkMatrix::I(),
correctedDomain, GrTextureDomain::kClamp_Mode, filter);
} else {
- fp = GrSimpleTextureEffect::Make(std::move(proxy), srcColorType, SkMatrix::I(), filter);
+ fp = GrSimpleTextureEffect::Make(sk_ref_sp(proxy), srcColorType, SkMatrix::I(), filter);
}
fp = GrColorSpaceXformEffect::Make(std::move(fp), std::move(textureXform));
paint.addColorFragmentProcessor(std::move(fp));
@@ -984,7 +1002,11 @@
aaFlags |= random->nextBool() ? GrQuadAAFlags::kBottom : GrQuadAAFlags::kNone;
bool useDomain = random->nextBool();
auto saturate = random->nextBool() ? GrTextureOp::Saturate::kYes : GrTextureOp::Saturate::kNo;
- return GrTextureOp::Make(context, std::move(proxy), GrColorType::kRGBA_8888,
+ GrSurfaceProxyView proxyView(
+ std::move(proxy), origin,
+ context->priv().caps()->getTextureSwizzle(format, GrColorType::kRGBA_8888));
+
+ return GrTextureOp::Make(context, std::move(proxyView), GrColorType::kRGBA_8888,
std::move(texXform), filter, color, saturate, SkBlendMode::kSrcOver,
aaType, aaFlags, GrQuad::MakeFromRect(rect, viewMatrix),
GrQuad(srcRect), useDomain ? &srcRect : nullptr);
diff --git a/src/gpu/ops/GrTextureOp.h b/src/gpu/ops/GrTextureOp.h
index da7a6b4..a4eb15b 100644
--- a/src/gpu/ops/GrTextureOp.h
+++ b/src/gpu/ops/GrTextureOp.h
@@ -40,7 +40,7 @@
* src over, this will return a GrFillRectOp with a paint that samples the proxy.
*/
std::unique_ptr<GrDrawOp> Make(GrRecordingContext*,
- sk_sp<GrTextureProxy>,
+ GrSurfaceProxyView,
GrColorType srcColorType,
sk_sp<GrColorSpaceXform>,
GrSamplerState::Filter,