Use GrSurfaceProxyView in RenderTasks.
Bug: skia:9556
Change-Id: Ibe0ae6981e87909848e5af73fc716aac7c8a591f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/249232
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrCopyRenderTask.cpp b/src/gpu/GrCopyRenderTask.cpp
index 9e44187..39fa454 100644
--- a/src/gpu/GrCopyRenderTask.cpp
+++ b/src/gpu/GrCopyRenderTask.cpp
@@ -11,15 +11,17 @@
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrResourceAllocator.h"
-sk_sp<GrRenderTask> GrCopyRenderTask::Make(sk_sp<GrSurfaceProxy> srcProxy,
+sk_sp<GrRenderTask> GrCopyRenderTask::Make(GrSurfaceProxyView srcView,
const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy,
+ GrSurfaceProxyView dstView,
const SkIPoint& dstPoint,
const GrCaps* caps) {
- SkASSERT(dstProxy);
- SkASSERT(srcProxy);
+ SkASSERT(dstView.proxy());
+ SkASSERT(srcView.proxy());
SkIRect clippedSrcRect;
SkIPoint clippedDstPoint;
+ GrSurfaceProxy* srcProxy = srcView.proxy();
+ GrSurfaceProxy* dstProxy = dstView.proxy();
// If the rect is outside the srcProxy or dstProxy then we've already succeeded.
if (!GrClipSrcRectAndDstPoint(dstProxy->dimensions(), srcProxy->dimensions(), srcRect, dstPoint,
&clippedSrcRect, &clippedDstPoint)) {
@@ -30,8 +32,8 @@
return nullptr;
}
- SkASSERT(dstProxy->origin() == srcProxy->origin());
- if (srcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
+ SkASSERT(dstView.origin() == srcView.origin());
+ if (srcView.origin() == kBottomLeft_GrSurfaceOrigin) {
int rectHeight = clippedSrcRect.height();
clippedSrcRect.fTop = srcProxy->height() - clippedSrcRect.fBottom;
clippedSrcRect.fBottom = clippedSrcRect.fTop + rectHeight;
@@ -39,44 +41,46 @@
}
sk_sp<GrCopyRenderTask> task(new GrCopyRenderTask(
- std::move(srcProxy), clippedSrcRect, std::move(dstProxy), clippedDstPoint));
+ std::move(srcView), clippedSrcRect, std::move(dstView), clippedDstPoint));
return task;
}
-GrCopyRenderTask::GrCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy,
+GrCopyRenderTask::GrCopyRenderTask(GrSurfaceProxyView srcView,
const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy,
+ GrSurfaceProxyView dstView,
const SkIPoint& dstPoint)
- : GrRenderTask(std::move(dstProxy))
- , fSrcProxy(std::move(srcProxy))
+ : GrRenderTask(std::move(dstView))
+ , fSrcView(std::move(srcView))
, fSrcRect(srcRect)
, fDstPoint(dstPoint) {
- fTarget->setLastRenderTask(this);
+ fTargetView.proxy()->setLastRenderTask(this);
}
void GrCopyRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
// This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
// fEndOfOpsTaskOpIndices will remain in sync), so we create a fake op# to capture the fact that
- // we read fSrcProxy and copy to fTarget.
- alloc->addInterval(fSrcProxy.get(), alloc->curOp(), alloc->curOp(),
+ // we read fSrcView and copy to fTargetView.
+ alloc->addInterval(fSrcView.proxy(), alloc->curOp(), alloc->curOp(),
GrResourceAllocator::ActualUse::kYes);
- alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
+ alloc->addInterval(fTargetView.proxy(), alloc->curOp(), alloc->curOp(),
GrResourceAllocator::ActualUse::kYes);
alloc->incOps();
}
bool GrCopyRenderTask::onExecute(GrOpFlushState* flushState) {
- if (!fSrcProxy->isInstantiated() || !fTarget->isInstantiated()) {
+ GrSurfaceProxy* dstProxy = fTargetView.proxy();
+ GrSurfaceProxy* srcProxy = fSrcView.proxy();
+ if (!srcProxy->isInstantiated() || !dstProxy->isInstantiated()) {
return false;
}
- GrSurface* srcSurface = fSrcProxy->peekSurface();
- GrSurface* dstSurface = fTarget->peekSurface();
- if (fSrcProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
- if (fSrcProxy->height() != srcSurface->height()) {
- fSrcRect.offset(0, srcSurface->height() - fSrcProxy->height());
+ GrSurface* srcSurface = srcProxy->peekSurface();
+ GrSurface* dstSurface = dstProxy->peekSurface();
+ if (fSrcView.origin() == kBottomLeft_GrSurfaceOrigin) {
+ if (srcProxy->height() != srcSurface->height()) {
+ fSrcRect.offset(0, srcSurface->height() - srcProxy->height());
}
- if (fTarget->height() != dstSurface->height()) {
- fDstPoint.fY = fDstPoint.fY + (dstSurface->height() - fTarget->height());
+ if (dstProxy->height() != dstSurface->height()) {
+ fDstPoint.fY = fDstPoint.fY + (dstSurface->height() - dstProxy->height());
}
}
return flushState->gpu()->copySurface(dstSurface, srcSurface, fSrcRect, fDstPoint);
diff --git a/src/gpu/GrCopyRenderTask.h b/src/gpu/GrCopyRenderTask.h
index 640bb11..c4f839c 100644
--- a/src/gpu/GrCopyRenderTask.h
+++ b/src/gpu/GrCopyRenderTask.h
@@ -12,21 +12,22 @@
class GrCopyRenderTask final : public GrRenderTask {
public:
- static sk_sp<GrRenderTask> Make(sk_sp<GrSurfaceProxy> srcProxy,
+ static sk_sp<GrRenderTask> Make(GrSurfaceProxyView srcView,
const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy,
+ GrSurfaceProxyView dstView,
const SkIPoint& dstPoint,
const GrCaps*);
private:
- GrCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy,
+ GrCopyRenderTask(GrSurfaceProxyView srcView,
const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy,
+ GrSurfaceProxyView dstView,
const SkIPoint& dstPoint);
bool onIsUsed(GrSurfaceProxy* proxy) const override {
- SkASSERT(proxy != fTarget.get()); // This case should be handled by GrRenderTask.
- return proxy == fSrcProxy.get();
+ // This case should be handled by GrRenderTask.
+ SkASSERT(proxy != fTargetView.proxy());
+ return proxy == fSrcView.proxy();
}
// If instantiation failed, at flush time we simply will skip doing the copy.
void handleInternalAllocationFailure() override {}
@@ -40,11 +41,11 @@
#ifdef SK_DEBUG
void visitProxies_debugOnly(const VisitSurfaceProxyFunc& fn) const override {
- fn(fSrcProxy.get(), GrMipMapped::kNo);
+ fn(fSrcView.proxy(), GrMipMapped::kNo);
}
#endif
- sk_sp<GrSurfaceProxy> fSrcProxy;
+ GrSurfaceProxyView fSrcView;
SkIRect fSrcRect;
SkIPoint fDstPoint;
};
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index ba89eca..ee7c1cd 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -128,7 +128,7 @@
GrOpsTask* curOpsTask = fRenderTasks[i]->asOpsTask();
if (prevOpsTask && curOpsTask) {
- SkASSERT(prevOpsTask->fTarget.get() != curOpsTask->fTarget.get());
+ SkASSERT(prevOpsTask->fTargetView != curOpsTask->fTargetView);
}
prevOpsTask = curOpsTask;
@@ -670,15 +670,17 @@
}
}
-sk_sp<GrOpsTask> GrDrawingManager::newOpsTask(sk_sp<GrRenderTargetProxy> rtp, bool managedOpsTask) {
+sk_sp<GrOpsTask> GrDrawingManager::newOpsTask(GrSurfaceProxyView surfaceView,
+ bool managedOpsTask) {
SkDEBUGCODE(this->validate());
SkASSERT(fContext);
- this->closeRenderTasksForNewRenderTask(rtp.get());
+ GrSurfaceProxy* proxy = surfaceView.proxy();
+ this->closeRenderTasksForNewRenderTask(proxy);
- sk_sp<GrOpsTask> opsTask(new GrOpsTask(fContext->priv().refOpMemoryPool(), rtp,
- fContext->priv().auditTrail()));
- SkASSERT(rtp->getLastRenderTask() == opsTask.get());
+ sk_sp<GrOpsTask> opsTask(new GrOpsTask(fContext->priv().refOpMemoryPool(),
+ std::move(surfaceView), fContext->priv().auditTrail()));
+ SkASSERT(proxy->getLastRenderTask() == opsTask.get());
if (managedOpsTask) {
fDAG.add(opsTask);
@@ -714,7 +716,8 @@
const GrCaps& caps = *fContext->priv().caps();
- sk_sp<GrWaitRenderTask> waitTask = sk_make_sp<GrWaitRenderTask>(proxy, std::move(semaphores),
+ sk_sp<GrWaitRenderTask> waitTask = sk_make_sp<GrWaitRenderTask>(GrSurfaceProxyView(proxy),
+ std::move(semaphores),
numSemaphores);
if (fReduceOpsTaskSplitting) {
GrRenderTask* lastTask = proxy->getLastRenderTask();
@@ -745,7 +748,7 @@
}
fDAG.add(waitTask);
} else {
- if (fActiveOpsTask && (fActiveOpsTask->fTarget == proxy)) {
+ if (fActiveOpsTask && (fActiveOpsTask->fTargetView.proxy() == proxy.get())) {
SkASSERT(proxy->getLastRenderTask() == fActiveOpsTask);
fDAG.addBeforeLast(waitTask);
// In this case we keep the current renderTask open but just insert the new waitTask
@@ -808,26 +811,28 @@
SkDEBUGCODE(this->validate());
}
-bool GrDrawingManager::newCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy,
+bool GrDrawingManager::newCopyRenderTask(GrSurfaceProxyView srcView,
const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy,
+ GrSurfaceProxyView dstView,
const SkIPoint& dstPoint) {
SkDEBUGCODE(this->validate());
SkASSERT(fContext);
- this->closeRenderTasksForNewRenderTask(dstProxy.get());
+ this->closeRenderTasksForNewRenderTask(dstView.proxy());
const GrCaps& caps = *fContext->priv().caps();
+ GrSurfaceProxy* srcProxy = srcView.proxy();
+
GrRenderTask* task =
- fDAG.add(GrCopyRenderTask::Make(srcProxy, srcRect, dstProxy, dstPoint, &caps));
+ fDAG.add(GrCopyRenderTask::Make(std::move(srcView), srcRect, std::move(dstView),
+ dstPoint, &caps));
if (!task) {
return false;
}
-
// We always say GrMipMapped::kNo here since we are always just copying from the base layer to
// another base layer. We don't need to make sure the whole mip map chain is valid.
- task->addDependency(srcProxy.get(), GrMipMapped::kNo, GrTextureResolveManager(this), caps);
+ task->addDependency(srcProxy, GrMipMapped::kNo, GrTextureResolveManager(this), caps);
task->makeClosed(caps);
// We have closed the previous active oplist but since a new oplist isn't being added there
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index 72f3211..8db8369 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -26,6 +26,7 @@
class GrRenderTargetContext;
class GrRenderTargetProxy;
class GrSoftwarePathRenderer;
+class GrSurfaceProxyView;
class GrTextureContext;
class GrTextureResolveRenderTask;
class SkDeferredDisplayList;
@@ -48,7 +49,7 @@
// A managed opsTask is controlled by the drawing manager (i.e., sorted & flushed with the
// others). An unmanaged one is created and used by the onFlushCallback.
- sk_sp<GrOpsTask> newOpsTask(sk_sp<GrRenderTargetProxy>, bool managedOpsTask);
+ sk_sp<GrOpsTask> newOpsTask(GrSurfaceProxyView, bool managedOpsTask);
// Create a render task that can resolve MSAA and/or regenerate mipmap levels on proxies. This
// method will only add the new render task to the list. It is up to the caller to call
@@ -72,14 +73,14 @@
GrColorType surfaceColorType, GrColorType dstColorType,
sk_sp<GrGpuBuffer> dstBuffer, size_t dstOffset);
- // Creates a new render task which copies a pixel rectangle from srcProxy into dstProxy. The src
+ // Creates a new render task which copies a pixel rectangle from srcView into dstView. The src
// pixels copied are specified by srcRect. They are copied to a rect of the same size in
// dstProxy with top left at dstPoint. If the src rect is clipped by the src bounds then pixel
// values in the dst rect corresponding to the area clipped by the src rect are not overwritten.
// This method is not guaranteed to succeed depending on the type of surface, formats, etc, and
// the backend-specific limitations.
- bool newCopyRenderTask(sk_sp<GrSurfaceProxy> srcProxy, const SkIRect& srcRect,
- sk_sp<GrSurfaceProxy> dstProxy, const SkIPoint& dstPoint);
+ bool newCopyRenderTask(GrSurfaceProxyView srcView, const SkIRect& srcRect,
+ GrSurfaceProxyView dstView, const SkIPoint& dstPoint);
GrRecordingContext* getContext() { return fContext; }
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index 2cf4af8..8cb748f 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -50,7 +50,8 @@
}
auto task = static_cast<GrTextureResolveRenderTask*>(fDrawingMgr->fOnFlushRenderTasks.push_back(
sk_make_sp<GrTextureResolveRenderTask>()).get());
- task->addProxy(textureProxy, resolveFlags, *this->caps());
+ task->addProxy(GrSurfaceProxyView(textureProxy, textureProxy->origin(), GrSwizzle()),
+ resolveFlags, *this->caps());
task->makeClosed(*this->caps());
}
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index 27dac24..1ee262d 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -15,6 +15,7 @@
#include "src/gpu/GrBufferAllocPool.h"
#include "src/gpu/GrDeferredUpload.h"
#include "src/gpu/GrRenderTargetProxy.h"
+#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
class GrGpu;
@@ -57,21 +58,22 @@
/** Additional data required on a per-op basis when executing GrOps. */
struct OpArgs {
- explicit OpArgs(GrOp* op, GrRenderTargetProxy* proxy, GrAppliedClip* appliedClip,
+ explicit OpArgs(GrOp* op, GrSurfaceProxyView* surfaceView, GrAppliedClip* appliedClip,
const GrXferProcessor::DstProxy& dstProxy)
- : fOp(op)
- , fProxy(proxy)
- , fAppliedClip(appliedClip)
- , fDstProxy(dstProxy) {
+ : fOp(op)
+ , fSurfaceView(surfaceView)
+ , fAppliedClip(appliedClip)
+ , fDstProxy(dstProxy) {
+ SkASSERT(surfaceView->asRenderTargetProxy());
}
- int numSamples() const { return fProxy->numSamples(); }
- GrSurfaceOrigin origin() const { return fProxy->origin(); }
- GrSwizzle outputSwizzle() const { return fProxy->outputSwizzle(); }
+ int numSamples() const { return this->proxy()->numSamples(); }
+ GrSurfaceOrigin origin() const { return fSurfaceView->origin(); }
+ GrSwizzle outputSwizzle() const { return fSurfaceView->swizzle(); }
GrOp* op() { return fOp; }
- GrRenderTargetProxy* proxy() const { return fProxy; }
- GrRenderTarget* renderTarget() const { return fProxy->peekRenderTarget(); }
+ GrRenderTargetProxy* proxy() const { return fSurfaceView->asRenderTargetProxy(); }
+ GrRenderTarget* renderTarget() const { return this->proxy()->peekRenderTarget(); }
GrAppliedClip* appliedClip() { return fAppliedClip; }
const GrAppliedClip* appliedClip() const { return fAppliedClip; }
const GrXferProcessor::DstProxy& dstProxy() const { return fDstProxy; }
@@ -79,13 +81,13 @@
#ifdef SK_DEBUG
void validate() const {
SkASSERT(fOp);
- SkASSERT(fProxy);
+ SkASSERT(fSurfaceView);
}
#endif
private:
GrOp* fOp;
- GrRenderTargetProxy* fProxy;
+ GrSurfaceProxyView* fSurfaceView;
GrAppliedClip* fAppliedClip;
GrXferProcessor::DstProxy fDstProxy; // TODO: do we still need the dst proxy here?
};
diff --git a/src/gpu/GrOpsTask.cpp b/src/gpu/GrOpsTask.cpp
index 4306ad0..2d61afe 100644
--- a/src/gpu/GrOpsTask.cpp
+++ b/src/gpu/GrOpsTask.cpp
@@ -352,15 +352,15 @@
////////////////////////////////////////////////////////////////////////////////
GrOpsTask::GrOpsTask(sk_sp<GrOpMemoryPool> opMemoryPool,
- sk_sp<GrRenderTargetProxy> rtProxy,
+ GrSurfaceProxyView view,
GrAuditTrail* auditTrail)
- : GrRenderTask(std::move(rtProxy))
+ : GrRenderTask(std::move(view))
, fOpMemoryPool(std::move(opMemoryPool))
, fAuditTrail(auditTrail)
, fLastClipStackGenID(SK_InvalidUniqueID)
SkDEBUGCODE(, fNumClips(0)) {
SkASSERT(fOpMemoryPool);
- fTarget->setLastRenderTask(this);
+ fTargetView.proxy()->setLastRenderTask(this);
}
void GrOpsTask::deleteOps() {
@@ -381,11 +381,12 @@
this->deleteOps();
fClipAllocator.reset();
- if (fTarget && this == fTarget->getLastRenderTask()) {
- fTarget->setLastRenderTask(nullptr);
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ if (proxy && this == proxy->getLastRenderTask()) {
+ proxy->setLastRenderTask(nullptr);
}
- fTarget.reset();
+ fTargetView.reset();
fDeferredProxies.reset();
fSampledProxies.reset();
fAuditTrail = nullptr;
@@ -412,7 +413,7 @@
}
void GrOpsTask::onPrepare(GrOpFlushState* flushState) {
- SkASSERT(fTarget->peekRenderTarget());
+ SkASSERT(fTargetView.proxy()->peekRenderTarget());
SkASSERT(this->isClosed());
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
@@ -433,7 +434,7 @@
TRACE_EVENT0("skia.gpu", chain.head()->name());
#endif
GrOpFlushState::OpArgs opArgs(chain.head(),
- fTarget->asRenderTargetProxy(),
+ &fTargetView,
chain.appliedClip(),
chain.dstProxy());
@@ -482,7 +483,9 @@
return false;
}
- SkASSERT(fTarget->peekRenderTarget());
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ SkASSERT(proxy);
+ SkASSERT(proxy->peekRenderTarget());
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
// Make sure load ops are not kClear if the GPU needs to use draws for clears
@@ -490,7 +493,7 @@
!flushState->gpu()->caps()->performColorClearsAsDraws());
const GrCaps& caps = *flushState->gpu()->caps();
- GrRenderTarget* renderTarget = fTarget.get()->peekRenderTarget();
+ GrRenderTarget* renderTarget = proxy->peekRenderTarget();
SkASSERT(renderTarget);
GrStencilAttachment* stencil = renderTarget->renderTargetPriv().getStencilAttachment();
@@ -536,7 +539,7 @@
: GrStoreOp::kStore;
GrOpsRenderPass* renderPass = create_render_pass(
- flushState->gpu(), fTarget->peekRenderTarget(), fTarget->origin(),
+ flushState->gpu(), proxy->peekRenderTarget(), fTargetView.origin(),
fClippedContentBounds, fColorLoadOp, fLoadClearColor, stencilLoadOp, stencilStoreOp,
fSampledProxies);
flushState->setOpsRenderPass(renderPass);
@@ -552,7 +555,7 @@
#endif
GrOpFlushState::OpArgs opArgs(chain.head(),
- fTarget->asRenderTargetProxy(),
+ &fTargetView,
chain.appliedClip(),
chain.dstProxy());
@@ -572,7 +575,9 @@
fColorLoadOp = op;
fLoadClearColor = color;
if (GrLoadOp::kClear == fColorLoadOp) {
- fTotalBounds = fTarget->getBoundsRect();
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ SkASSERT(proxy);
+ fTotalBounds = proxy->getBoundsRect();
}
}
@@ -591,7 +596,7 @@
// If the opsTask is using a render target which wraps a vulkan command buffer, we can't do
// a clear load since we cannot change the render pass that we are using. Thus we fall back
// to making a clear op in this case.
- return !fTarget->asRenderTargetProxy()->wrapsVkSecondaryCB();
+ return !fTargetView.asRenderTargetProxy()->wrapsVkSecondaryCB();
}
// Could not empty the task, so an op must be added to handle the clear
@@ -717,24 +722,26 @@
alloc->addInterval(fDeferredProxies[i], 0, 0, GrResourceAllocator::ActualUse::kNo);
}
+ GrSurfaceProxy* targetProxy = fTargetView.proxy();
+
// Add the interval for all the writes to this GrOpsTasks's target
if (fOpChains.count()) {
unsigned int cur = alloc->curOp();
- alloc->addInterval(fTarget.get(), cur, cur + fOpChains.count() - 1,
+ alloc->addInterval(targetProxy, cur, cur + fOpChains.count() - 1,
GrResourceAllocator::ActualUse::kYes);
} else {
// This can happen if there is a loadOp (e.g., a clear) but no other draws. In this case we
// still need to add an interval for the destination so we create a fake op# for
// the missing clear op.
- alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
+ alloc->addInterval(targetProxy, alloc->curOp(), alloc->curOp(),
GrResourceAllocator::ActualUse::kYes);
alloc->incOps();
}
auto gather = [ alloc SkDEBUGCODE(, this) ] (GrSurfaceProxy* p, GrMipMapped) {
alloc->addInterval(p, alloc->curOp(), alloc->curOp(), GrResourceAllocator::ActualUse::kYes
- SkDEBUGCODE(, fTarget.get() == p));
+ SkDEBUGCODE(, fTargetView.proxy() == p));
};
for (const OpChain& recordedOp : fOpChains) {
recordedOp.visitProxies(gather);
@@ -750,7 +757,8 @@
const DstProxy* dstProxy, const GrCaps& caps) {
SkDEBUGCODE(op->validate();)
SkASSERT(processorAnalysis.requiresDstTexture() == (dstProxy && dstProxy->proxy()));
- SkASSERT(fTarget);
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ SkASSERT(proxy);
// A closed GrOpsTask should never receive new/more ops
SkASSERT(!this->isClosed());
@@ -767,7 +775,7 @@
// 1) check every op
// 2) intersect with something
// 3) find a 'blocker'
- GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), fTarget->uniqueID());
+ GR_AUDIT_TRAIL_ADD_OP(fAuditTrail, op.get(), proxy->uniqueID());
GrOP_INFO("opsTask: %d Recording (%s, opID: %u)\n"
"\tBounds [L: %.2f, T: %.2f R: %.2f B: %.2f]\n",
this->uniqueID(),
@@ -843,9 +851,10 @@
const GrCaps& caps, SkIRect* targetUpdateBounds) {
this->forwardCombine(caps);
if (!this->isNoOp()) {
- SkRect clippedContentBounds = fTarget->getBoundsRect();
- // TODO: If we can fix up GLPrograms test to always intersect the fTarget bounds then we can
- // simply assert here that the bounds intersect.
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ SkRect clippedContentBounds = proxy->getBoundsRect();
+ // TODO: If we can fix up GLPrograms test to always intersect the fTargetView proxy bounds
+ // then we can simply assert here that the bounds intersect.
if (clippedContentBounds.intersect(fTotalBounds)) {
clippedContentBounds.roundOut(&fClippedContentBounds);
*targetUpdateBounds = fClippedContentBounds;
diff --git a/src/gpu/GrOpsTask.h b/src/gpu/GrOpsTask.h
index c223812..61507e3 100644
--- a/src/gpu/GrOpsTask.h
+++ b/src/gpu/GrOpsTask.h
@@ -38,7 +38,7 @@
using DstProxy = GrXferProcessor::DstProxy;
public:
- GrOpsTask(sk_sp<GrOpMemoryPool>, sk_sp<GrRenderTargetProxy>, GrAuditTrail*);
+ GrOpsTask(sk_sp<GrOpMemoryPool>, GrSurfaceProxyView, GrAuditTrail*);
~GrOpsTask() override;
GrOpsTask* asOpsTask() override { return this; }
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 9e7b6ce..9b5dd49 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -217,7 +217,7 @@
if (!fOpsTask || fOpsTask->isClosed()) {
sk_sp<GrOpsTask> newOpsTask =
- this->drawingManager()->newOpsTask(fRenderTargetProxy, fManagedOpsTask);
+ this->drawingManager()->newOpsTask(this->outputSurfaceView(), fManagedOpsTask);
if (fOpsTask && fNumStencilSamples > 0) {
// Store the stencil values in memory upon completion of fOpsTask.
fOpsTask->setMustPreserveStencil();
diff --git a/src/gpu/GrRenderTask.cpp b/src/gpu/GrRenderTask.cpp
index 2f6c0e6..4699893 100644
--- a/src/gpu/GrRenderTask.cpp
+++ b/src/gpu/GrRenderTask.cpp
@@ -21,16 +21,22 @@
return id;
}
-GrRenderTask::GrRenderTask(sk_sp<GrSurfaceProxy> target)
- : fTarget(std::move(target))
+GrRenderTask::GrRenderTask()
+ : fUniqueID(CreateUniqueID())
+ , fFlags(0) {
+}
+
+GrRenderTask::GrRenderTask(GrSurfaceProxyView targetView)
+ : fTargetView(std::move(targetView))
, fUniqueID(CreateUniqueID())
, fFlags(0) {
}
GrRenderTask::~GrRenderTask() {
- if (fTarget && this == fTarget->getLastRenderTask()) {
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ if (proxy && this == proxy->getLastRenderTask()) {
// Ensure the target proxy doesn't keep hold of a dangling back pointer.
- fTarget->setLastRenderTask(nullptr);
+ proxy->setLastRenderTask(nullptr);
}
}
@@ -53,12 +59,13 @@
SkIRect targetUpdateBounds;
if (ExpectedOutcome::kTargetDirty == this->onMakeClosed(caps, &targetUpdateBounds)) {
- SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(targetUpdateBounds));
- if (fTarget->requiresManualMSAAResolve()) {
- SkASSERT(fTarget->asRenderTargetProxy());
- fTarget->asRenderTargetProxy()->markMSAADirty(targetUpdateBounds);
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ SkASSERT(SkIRect::MakeSize(proxy->dimensions()).contains(targetUpdateBounds));
+ if (proxy->requiresManualMSAAResolve()) {
+ SkASSERT(fTargetView.asRenderTargetProxy());
+ fTargetView.asRenderTargetProxy()->markMSAADirty(targetUpdateBounds);
}
- GrTextureProxy* textureProxy = fTarget->asTextureProxy();
+ GrTextureProxy* textureProxy = fTargetView.asTextureProxy();
if (textureProxy && GrMipMapped::kYes == textureProxy->mipMapped()) {
textureProxy->markMipMapsDirty();
}
@@ -161,7 +168,9 @@
if (!fTextureResolveTask) {
fTextureResolveTask = textureResolveManager.newTextureResolveRenderTask(caps);
}
- fTextureResolveTask->addProxy(sk_ref_sp(dependedOn), resolveFlags, caps);
+ fTextureResolveTask->addProxy(
+ GrSurfaceProxyView(sk_ref_sp(dependedOn), dependedOn->origin(), GrSwizzle()),
+ resolveFlags, caps);
// addProxy() should have closed the texture proxy's previous task.
SkASSERT(!dependedOnTask || dependedOnTask->isClosed());
@@ -244,20 +253,21 @@
bool GrRenderTask::isInstantiated() const {
// Some renderTasks (e.g. GrTransferFromRenderTask) don't have a target.
- if (!fTarget) {
+ GrSurfaceProxy* proxy = fTargetView.proxy();
+ if (!proxy) {
return true;
}
- if (!fTarget->isInstantiated()) {
+ if (!proxy->isInstantiated()) {
return false;
}
- int minStencilSampleCount = (fTarget->asRenderTargetProxy())
- ? fTarget->asRenderTargetProxy()->numStencilSamples()
+ int minStencilSampleCount = (proxy->asRenderTargetProxy())
+ ? proxy->asRenderTargetProxy()->numStencilSamples()
: 0;
if (minStencilSampleCount) {
- GrRenderTarget* rt = fTarget->peekRenderTarget();
+ GrRenderTarget* rt = proxy->peekRenderTarget();
SkASSERT(rt);
GrStencilAttachment* stencil = rt->renderTargetPriv().getStencilAttachment();
@@ -267,7 +277,7 @@
SkASSERT(stencil->numSamples() >= minStencilSampleCount);
}
- GrSurface* surface = fTarget->peekSurface();
+ GrSurface* surface = proxy->peekSurface();
if (surface->wasDestroyed()) {
return false;
}
@@ -278,10 +288,11 @@
#ifdef SK_DEBUG
void GrRenderTask::dump(bool printDependencies) const {
SkDebugf("--------------------------------------------------------------\n");
+ GrSurfaceProxy* proxy = fTargetView.proxy();
SkDebugf("renderTaskID: %d - proxyID: %d - surfaceID: %d\n", fUniqueID,
- fTarget ? fTarget->uniqueID().asUInt() : -1,
- fTarget && fTarget->peekSurface()
- ? fTarget->peekSurface()->uniqueID().asUInt()
+ proxy ? proxy->uniqueID().asUInt() : -1,
+ proxy && proxy->peekSurface()
+ ? proxy->peekSurface()->uniqueID().asUInt()
: -1);
if (printDependencies) {
diff --git a/src/gpu/GrRenderTask.h b/src/gpu/GrRenderTask.h
index 3fb3a18..efa1305 100644
--- a/src/gpu/GrRenderTask.h
+++ b/src/gpu/GrRenderTask.h
@@ -11,6 +11,7 @@
#include "include/core/SkRefCnt.h"
#include "include/private/SkColorData.h"
#include "include/private/SkTDArray.h"
+#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/GrTextureResolveManager.h"
@@ -24,7 +25,8 @@
// contents. (e.g., an opsTask that executes a command buffer, a task to regenerate mipmaps, etc.)
class GrRenderTask : public SkRefCnt {
public:
- GrRenderTask(sk_sp<GrSurfaceProxy> target);
+ GrRenderTask();
+ GrRenderTask(GrSurfaceProxyView);
~GrRenderTask() override;
void makeClosed(const GrCaps&);
@@ -80,8 +82,8 @@
void visitTargetAndSrcProxies_debugOnly(const VisitSurfaceProxyFunc& fn) const {
this->visitProxies_debugOnly(fn);
- if (fTarget) {
- fn(fTarget.get(), GrMipMapped::kNo);
+ if (fTargetView.proxy()) {
+ fn(fTargetView.proxy(), GrMipMapped::kNo);
}
}
#endif
@@ -105,7 +107,7 @@
// targetUpdateBounds must not extend beyond the proxy bounds.
virtual ExpectedOutcome onMakeClosed(const GrCaps&, SkIRect* targetUpdateBounds) = 0;
- sk_sp<GrSurfaceProxy> fTarget;
+ GrSurfaceProxyView fTargetView;
// List of texture proxies whose contents are being prepared on a worker thread
// TODO: this list exists so we can fire off the proper upload when an renderTask begins
@@ -117,14 +119,14 @@
friend class GrDrawingManager;
// Drops any pending operations that reference proxies that are not instantiated.
- // NOTE: Derived classes don't need to check fTarget. That is handled when the drawingManager
- // calls isInstantiated.
+ // NOTE: Derived classes don't need to check fTargetView. That is handled when the
+ // drawingManager calls isInstantiated.
virtual void handleInternalAllocationFailure() = 0;
virtual bool onIsUsed(GrSurfaceProxy*) const = 0;
bool isUsed(GrSurfaceProxy* proxy) const {
- if (proxy == fTarget.get()) {
+ if (proxy == fTargetView.proxy()) {
return true;
}
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index f427478..8d4708d 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -430,8 +430,10 @@
return false;
}
- return this->drawingManager()->newCopyRenderTask(sk_ref_sp(src), srcRect,
- this->asSurfaceProxyRef(), dstPoint);
+ // The swizzle doesn't matter for copies and it is not used.
+ return this->drawingManager()->newCopyRenderTask(
+ GrSurfaceProxyView(sk_ref_sp(src), src->origin(), GrSwizzle()), srcRect,
+ this->textureSurfaceView(), dstPoint);
}
std::unique_ptr<GrRenderTargetContext> GrSurfaceContext::rescale(
diff --git a/src/gpu/GrSurfaceContext.h b/src/gpu/GrSurfaceContext.h
index 0d2c4b3..b30e531 100644
--- a/src/gpu/GrSurfaceContext.h
+++ b/src/gpu/GrSurfaceContext.h
@@ -105,7 +105,6 @@
}
#endif
-
protected:
friend class GrSurfaceContextPriv;
diff --git a/src/gpu/GrSurfaceProxyView.h b/src/gpu/GrSurfaceProxyView.h
index 9f81713..1649e12 100644
--- a/src/gpu/GrSurfaceProxyView.h
+++ b/src/gpu/GrSurfaceProxyView.h
@@ -15,22 +15,41 @@
class GrSurfaceProxyView {
public:
+ GrSurfaceProxyView() = default;
+
GrSurfaceProxyView(sk_sp<GrSurfaceProxy> proxy, GrSurfaceOrigin origin, GrSwizzle swizzle)
: fProxy(proxy), fOrigin(origin), fSwizzle(swizzle) {}
- GrSurfaceProxyView(GrSurfaceProxyView&& view)
- : fProxy(std::move(view.fProxy)), fOrigin(view.fOrigin), fSwizzle(view.fSwizzle) {}
+ // This entry point is used when we don't care about the origin or the swizzle.
+ GrSurfaceProxyView(sk_sp<GrSurfaceProxy> proxy)
+ : fProxy(proxy), fOrigin(kTopLeft_GrSurfaceOrigin) {}
- GrSurfaceProxy* asSurfaceProxy() const { return fProxy.get(); }
+ GrSurfaceProxyView(GrSurfaceProxyView&& view) = default;
+ GrSurfaceProxyView(const GrSurfaceProxyView&) = delete;
+
+ GrSurfaceProxyView& operator=(const GrSurfaceProxyView& that) = default;
+
+ bool operator==(const GrSurfaceProxyView& view) {
+ return fProxy.get() == view.fProxy.get() &&
+ fOrigin == view.fOrigin &&
+ fSwizzle == view.fSwizzle;
+ }
+ bool operator!=(const GrSurfaceProxyView& other) { return !(*this == other); }
+
+ GrSurfaceProxy* proxy() const { return fProxy.get(); }
GrTextureProxy* asTextureProxy() const { return fProxy->asTextureProxy(); }
GrRenderTargetProxy* asRenderTargetProxy() const { return fProxy->asRenderTargetProxy(); }
GrSurfaceOrigin origin() const { return fOrigin; }
const GrSwizzle& swizzle() const { return fSwizzle; }
+ void reset() {
+ *this = {};
+ }
+
private:
sk_sp<GrSurfaceProxy> fProxy;
- GrSurfaceOrigin fOrigin;
+ GrSurfaceOrigin fOrigin = kTopLeft_GrSurfaceOrigin;
GrSwizzle fSwizzle;
};
diff --git a/src/gpu/GrTextureResolveRenderTask.cpp b/src/gpu/GrTextureResolveRenderTask.cpp
index e12bbc8..8c326d3 100644
--- a/src/gpu/GrTextureResolveRenderTask.cpp
+++ b/src/gpu/GrTextureResolveRenderTask.cpp
@@ -17,14 +17,14 @@
GrTextureResolveRenderTask::~GrTextureResolveRenderTask() {
for (const auto& resolve : fResolves) {
// Ensure the proxy doesn't keep hold of a dangling back pointer.
- resolve.fProxy->setLastRenderTask(nullptr);
+ resolve.fProxyView.proxy()->setLastRenderTask(nullptr);
}
}
void GrTextureResolveRenderTask::addProxy(
- sk_sp<GrSurfaceProxy> proxyHolder, GrSurfaceProxy::ResolveFlags flags, const GrCaps& caps) {
- fResolves.emplace_back(std::move(proxyHolder), flags);
- GrSurfaceProxy* proxy = fResolves.back().fProxy.get();
+ GrSurfaceProxyView proxyView, GrSurfaceProxy::ResolveFlags flags, const GrCaps& caps) {
+ fResolves.emplace_back(std::move(proxyView), flags);
+ GrSurfaceProxy* proxy = fResolves.back().fProxyView.proxy();
// Ensure the last render task that operated on the proxy is closed. That's where msaa and
// mipmaps should have been marked dirty.
@@ -58,7 +58,7 @@
// manipulate the resolve proxies.
auto fakeOp = alloc->curOp();
for (const auto& resolve : fResolves) {
- alloc->addInterval(resolve.fProxy.get(), fakeOp, fakeOp,
+ alloc->addInterval(resolve.fProxyView.proxy(), fakeOp, fakeOp,
GrResourceAllocator::ActualUse::kYes);
}
alloc->incOps();
@@ -68,10 +68,11 @@
// Resolve all msaa back-to-back, before regenerating mipmaps.
for (const auto& resolve : fResolves) {
if (GrSurfaceProxy::ResolveFlags::kMSAA & resolve.fFlags) {
+ GrSurfaceProxy* proxy = resolve.fProxyView.proxy();
// peekRenderTarget might be null if there was an instantiation error.
- if (GrRenderTarget* renderTarget = resolve.fProxy->peekRenderTarget()) {
+ if (GrRenderTarget* renderTarget = proxy->peekRenderTarget()) {
flushState->gpu()->resolveRenderTarget(renderTarget, resolve.fMSAAResolveRect,
- resolve.fProxy->origin(),
+ resolve.fProxyView.origin(),
GrGpu::ForExternalIO::kNo);
}
}
@@ -80,7 +81,7 @@
for (const auto& resolve : fResolves) {
if (GrSurfaceProxy::ResolveFlags::kMipMaps & resolve.fFlags) {
// peekTexture might be null if there was an instantiation error.
- GrTexture* texture = resolve.fProxy->peekTexture();
+ GrTexture* texture = resolve.fProxyView.proxy()->peekTexture();
if (texture && texture->texturePriv().mipMapsAreDirty()) {
flushState->gpu()->regenerateMipMapLevels(texture);
SkASSERT(!texture->texturePriv().mipMapsAreDirty());
@@ -94,7 +95,7 @@
#ifdef SK_DEBUG
void GrTextureResolveRenderTask::visitProxies_debugOnly(const VisitSurfaceProxyFunc& fn) const {
for (const auto& resolve : fResolves) {
- fn(resolve.fProxy.get(), GrMipMapped::kNo);
+ fn(resolve.fProxyView.proxy(), GrMipMapped::kNo);
}
}
#endif
diff --git a/src/gpu/GrTextureResolveRenderTask.h b/src/gpu/GrTextureResolveRenderTask.h
index 48fea39..1a3aed0 100644
--- a/src/gpu/GrTextureResolveRenderTask.h
+++ b/src/gpu/GrTextureResolveRenderTask.h
@@ -12,14 +12,15 @@
class GrTextureResolveRenderTask final : public GrRenderTask {
public:
- GrTextureResolveRenderTask() : GrRenderTask(nullptr) {}
+ GrTextureResolveRenderTask() : GrRenderTask() {}
~GrTextureResolveRenderTask() override;
- void addProxy(sk_sp<GrSurfaceProxy>, GrSurfaceProxy::ResolveFlags, const GrCaps&);
+ void addProxy(GrSurfaceProxyView proxyView, GrSurfaceProxy::ResolveFlags, const GrCaps&);
private:
bool onIsUsed(GrSurfaceProxy* proxy) const override {
- SkASSERT(proxy != fTarget.get()); // This case should be handled by GrRenderTask.
+ // This case should be handled by GrRenderTask.
+ SkASSERT(proxy != fTargetView.proxy());
return false;
}
void handleInternalAllocationFailure() override {
@@ -38,9 +39,9 @@
#endif
struct Resolve {
- Resolve(sk_sp<GrSurfaceProxy> proxy, GrSurfaceProxy::ResolveFlags flags)
- : fProxy(std::move(proxy)), fFlags(flags) {}
- sk_sp<GrSurfaceProxy> fProxy;
+ Resolve(GrSurfaceProxyView proxyView, GrSurfaceProxy::ResolveFlags flags)
+ : fProxyView(std::move(proxyView)), fFlags(flags) {}
+ GrSurfaceProxyView fProxyView;
GrSurfaceProxy::ResolveFlags fFlags;
SkIRect fMSAAResolveRect;
};
diff --git a/src/gpu/GrTransferFromRenderTask.h b/src/gpu/GrTransferFromRenderTask.h
index 40e89da..d8f6c12 100644
--- a/src/gpu/GrTransferFromRenderTask.h
+++ b/src/gpu/GrTransferFromRenderTask.h
@@ -18,7 +18,7 @@
GrColorType dstColorType,
sk_sp<GrGpuBuffer> dstBuffer,
size_t dstOffset)
- : GrRenderTask(nullptr)
+ : GrRenderTask()
, fSrcProxy(std::move(srcProxy))
, fSrcRect(srcRect)
, fSurfaceColorType(surfaceColorType)
@@ -28,7 +28,7 @@
private:
bool onIsUsed(GrSurfaceProxy* proxy) const override {
- SkASSERT(!fTarget);
+ SkASSERT(!fTargetView.proxy());
return proxy == fSrcProxy.get();
}
// If fSrcProxy is uninstantiated at flush time we simply will skip doing the transfer.
diff --git a/src/gpu/GrWaitRenderTask.cpp b/src/gpu/GrWaitRenderTask.cpp
index a09a9a6..2d057fa 100644
--- a/src/gpu/GrWaitRenderTask.cpp
+++ b/src/gpu/GrWaitRenderTask.cpp
@@ -14,8 +14,8 @@
void GrWaitRenderTask::gatherProxyIntervals(GrResourceAllocator* alloc) const {
// This renderTask doesn't have "normal" ops. In this case we still need to add an interval (so
// fEndOfOpsTaskOpIndices will remain in sync), so we create a fake op# to capture the fact that
- // we manipulate fTarget.
- alloc->addInterval(fTarget.get(), alloc->curOp(), alloc->curOp(),
+ // we manipulate fTargetView's proxy.
+ alloc->addInterval(fTargetView.proxy(), alloc->curOp(), alloc->curOp(),
GrResourceAllocator::ActualUse::kYes);
alloc->incOps();
}
diff --git a/src/gpu/GrWaitRenderTask.h b/src/gpu/GrWaitRenderTask.h
index fc736e1..d3683f2 100644
--- a/src/gpu/GrWaitRenderTask.h
+++ b/src/gpu/GrWaitRenderTask.h
@@ -13,15 +13,17 @@
class GrWaitRenderTask final : public GrRenderTask {
public:
- GrWaitRenderTask(sk_sp<GrSurfaceProxy> proxy, std::unique_ptr<sk_sp<GrSemaphore>[]> semaphores,
+ GrWaitRenderTask(GrSurfaceProxyView surfaceView,
+ std::unique_ptr<sk_sp<GrSemaphore>[]> semaphores,
int numSemaphores)
- : GrRenderTask(std::move(proxy))
+ : GrRenderTask(std::move(surfaceView))
, fSemaphores(std::move(semaphores))
, fNumSemaphores(numSemaphores){}
private:
bool onIsUsed(GrSurfaceProxy* proxy) const override {
- SkASSERT(proxy != fTarget.get()); // This case should be handled by GrRenderTask.
+ // This case should be handled by GrRenderTask.
+ SkASSERT(proxy != fTargetView.proxy());
return false;
}
void handleInternalAllocationFailure() override {}
diff --git a/tests/DrawOpAtlasTest.cpp b/tests/DrawOpAtlasTest.cpp
index ec6068c..faccf27 100644
--- a/tests/DrawOpAtlasTest.cpp
+++ b/tests/DrawOpAtlasTest.cpp
@@ -211,8 +211,10 @@
TestingUploadTarget uploadTarget;
GrOpFlushState flushState(gpu, resourceProvider, uploadTarget.writeableTokenTracker());
+
+ GrSurfaceProxyView surfaceView = rtc->outputSurfaceView();
GrOpFlushState::OpArgs opArgs(op.get(),
- rtc->asRenderTargetProxy(),
+ &surfaceView,
nullptr,
GrXferProcessor::DstProxy(nullptr, SkIPoint::Make(0, 0)));
diff --git a/tests/OpChainTest.cpp b/tests/OpChainTest.cpp
index c662843..b2560a1 100644
--- a/tests/OpChainTest.cpp
+++ b/tests/OpChainTest.cpp
@@ -171,11 +171,16 @@
context->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
GrRenderable::kYes);
+ static const GrSurfaceOrigin kOrigin = kTopLeft_GrSurfaceOrigin;
auto proxy = context->priv().proxyProvider()->createProxy(
- format, desc, GrRenderable::kYes, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
+ format, desc, GrRenderable::kYes, 1, kOrigin, GrMipMapped::kNo,
SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, GrInternalSurfaceFlags::kNone);
SkASSERT(proxy);
proxy->instantiate(context->priv().resourceProvider());
+
+ GrSwizzle outSwizzle = context->priv().caps()->getOutputSwizzle(format,
+ GrColorType::kRGBA_8888);
+
int result[result_width()];
int validResult[result_width()];
@@ -206,7 +211,7 @@
context->priv().resourceProvider(),
&tracker);
GrOpsTask opsTask(context->priv().refOpMemoryPool(),
- sk_ref_sp(proxy->asRenderTargetProxy()),
+ GrSurfaceProxyView(proxy, kOrigin, outSwizzle),
context->priv().auditTrail());
// This assumes the particular values of kRanges.
std::fill_n(result, result_width(), -1);