aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-08-30 07:41:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-30 11:45:42 +0000
commit380b90c92bead0c1b869df08b2d2790c302c5c71 (patch)
tree06e2a81cbb53e417c5e483b24537a36d77cb33ce
parentfb4a20c7f54110d6c43dee4b78801c163ad6c8f3 (diff)
Push full screen clears up to OpList
Change-Id: Icfc09b3b25f4d3834bee93286e2b24a559f44ed8 Reviewed-on: https://skia-review.googlesource.com/40120 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
-rw-r--r--src/gpu/GrOpList.h3
-rw-r--r--src/gpu/GrRenderTargetContext.cpp17
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp52
-rw-r--r--src/gpu/GrRenderTargetOpList.h11
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp6
5 files changed, 38 insertions, 51 deletions
diff --git a/src/gpu/GrOpList.h b/src/gpu/GrOpList.h
index 50eaaef31f..b33c298eaf 100644
--- a/src/gpu/GrOpList.h
+++ b/src/gpu/GrOpList.h
@@ -101,8 +101,7 @@ public:
SkDEBUGCODE(virtual int numOps() const = 0;)
SkDEBUGCODE(virtual int numClips() const { return 0; })
- void setColorLoadOp(GrLoadOp loadOp) { fColorLoadOp = loadOp; }
- void setLoadClearColor(GrColor color) { fLoadClearColor = color; }
+ // TODO: it would be nice for this to be hidden
void setStencilLoadOp(GrLoadOp loadOp) { fStencilLoadOp = loadOp; }
protected:
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index cd881b44bd..b83e2530c1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -220,22 +220,7 @@ void GrRenderTargetContext::discard() {
AutoCheckFlush acf(this->drawingManager());
- // Discard calls to in-progress opLists are ignored. Calls at the start update the
- // opLists' color & stencil load ops.
- if (this->getRTOpList()->isEmpty()) {
- if (this->caps()->discardRenderTargetSupport()) {
- this->getRTOpList()->setColorLoadOp(GrLoadOp::kDiscard);
- this->getRTOpList()->setStencilLoadOp(GrLoadOp::kDiscard);
- } else {
- // skbug.com/6956 (Extra clear confuses Nexus7)
-#if 0
- // Surely, if a discard was requested, a clear should be acceptable
- this->getRTOpList()->setColorLoadOp(GrLoadOp::kClear);
- this->getRTOpList()->setLoadClearColor(0x0);
- this->getRTOpList()->setStencilLoadOp(GrLoadOp::kClear);
-#endif
- }
- }
+ this->getRTOpList()->discard();
}
void GrRenderTargetContext::clear(const SkIRect* rect,
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index ce34be7495..77b6eca3bc 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -133,7 +133,7 @@ static inline void finish_command_buffer(GrGpuRTCommandBuffer* buffer) {
// is at flush time). However, we need to store the RenderTargetProxy in the
// Ops and instantiate them here.
bool GrRenderTargetOpList::onExecute(GrOpFlushState* flushState) {
- if (0 == fRecordedOps.count()) {
+ if (0 == fRecordedOps.count() && GrLoadOp::kClear != fColorLoadOp) {
return false;
}
@@ -180,7 +180,6 @@ bool GrRenderTargetOpList::onExecute(GrOpFlushState* flushState) {
}
void GrRenderTargetOpList::reset() {
- fLastFullClearOp = nullptr;
fLastClipStackGenID = SK_InvalidUniqueID;
fRecordedOps.reset();
if (fInstancedRendering) {
@@ -203,30 +202,35 @@ void GrRenderTargetOpList::freeGpuResources() {
}
}
+void GrRenderTargetOpList::discard() {
+ // Discard calls to in-progress opLists are ignored. Calls at the start update the
+ // opLists' color & stencil load ops.
+ if (this->isEmpty()) {
+ fColorLoadOp = GrLoadOp::kDiscard;
+ fStencilLoadOp = GrLoadOp::kDiscard;
+ }
+}
+
void GrRenderTargetOpList::fullClear(const GrCaps& caps, GrColor color) {
- // Currently this just inserts or updates the last clear op. However, once in MDB this can
- // remove all the previously recorded ops and change the load op to clear with supplied
- // color.
- if (fLastFullClearOp) {
- // As currently implemented, fLastFullClearOp should be the last op because we would
- // have cleared it when another op was recorded.
- SkASSERT(fRecordedOps.back().fOp.get() == fLastFullClearOp);
- GrOP_INFO("opList: %d Fusing clears (opID: %d Color: 0x%08x -> 0x%08x)\n",
- this->uniqueID(),
- fLastFullClearOp->uniqueID(),
- fLastFullClearOp->color(), color);
- fLastFullClearOp->setColor(color);
+
+ // This is conservative. If the opList is marked as needing a stencil buffer then there
+ // may be a prior op that writes to the stencil buffer. Although the clear will ignore the
+ // stencil buffer, following draw ops may not so we can't get rid of all the preceding ops.
+ // Beware! If we ever add any ops that have a side effect beyond modifying the stencil
+ // buffer we will need a more elaborate tracking system (skbug.com/7002).
+ if (this->isEmpty() || !fTarget.get()->asRenderTargetProxy()->needsStencil()) {
+ fRecordedOps.reset();
+ fColorLoadOp = GrLoadOp::kClear;
+ fLoadClearColor = color;
return;
}
+
std::unique_ptr<GrClearOp> op(GrClearOp::Make(GrFixedClip::Disabled(), color, fTarget.get()));
if (!op) {
return;
}
- if (GrOp* clearOp = this->recordOp(std::move(op), caps)) {
- // This is either the clear op we just created or another one that it combined with.
- fLastFullClearOp = static_cast<GrClearOp*>(clearOp);
- }
+ this->recordOp(std::move(op), caps);
}
////////////////////////////////////////////////////////////////////////////////
@@ -277,10 +281,10 @@ bool GrRenderTargetOpList::combineIfPossible(const RecordedOp& a, GrOp* b,
return a.fOp->combineIfPossible(b, caps);
}
-GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
- const GrCaps& caps,
- GrAppliedClip* clip,
- const DstProxy* dstProxy) {
+void GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
+ const GrCaps& caps,
+ GrAppliedClip* clip,
+ const DstProxy* dstProxy) {
SkASSERT(fTarget.get());
// A closed GrOpList should never receive new/more ops
@@ -313,7 +317,7 @@ GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
GrOP_INFO("\t\t\tBackward: Combined op info:\n");
GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str());
GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get());
- return candidate.fOp.get();
+ return;
}
// Stop going backwards if we would cause a painter's order violation.
if (!can_reorder(fRecordedOps.fromBack(i).fOp->bounds(), op->bounds())) {
@@ -337,8 +341,6 @@ GrOp* GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op,
}
fRecordedOps.emplace_back(std::move(op), clip, dstProxy);
fRecordedOps.back().fOp->wasRecorded(this);
- fLastFullClearOp = nullptr;
- return fRecordedOps.back().fOp.get();
}
void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) {
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index b62cee5531..ef4bdacdd2 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -45,7 +45,6 @@ public:
return;
}
- fLastFullClearOp = nullptr;
this->forwardCombine(caps);
INHERITED::makeClosed(caps);
@@ -78,6 +77,8 @@ public:
return this->uniqueID();
}
+ void discard();
+
/** Clears the entire render target */
void fullClear(const GrCaps& caps, GrColor color);
@@ -124,10 +125,8 @@ private:
GrAppliedClip* fAppliedClip;
};
- // If the input op is combined with an earlier op, this returns the combined op. Otherwise, it
- // returns the input op.
- GrOp* recordOp(std::unique_ptr<GrOp>, const GrCaps& caps,
- GrAppliedClip* = nullptr, const DstProxy* = nullptr);
+ void recordOp(std::unique_ptr<GrOp>, const GrCaps& caps,
+ GrAppliedClip* = nullptr, const DstProxy* = nullptr);
void forwardCombine(const GrCaps&);
@@ -135,8 +134,6 @@ private:
bool combineIfPossible(const RecordedOp& a, GrOp* b, const GrAppliedClip* bClip,
const DstProxy* bDstTexture, const GrCaps&);
- GrClearOp* fLastFullClearOp = nullptr;
-
std::unique_ptr<gr_instanced::InstancedRendering> fInstancedRendering;
uint32_t fLastClipStackGenID;
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index f202c9b709..15fdf4aa78 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -116,7 +116,11 @@ void GrVkGpuRTCommandBuffer::init() {
cbInfo.fColorClearValue.color.float32[2] = fClearColor.fRGBA[2];
cbInfo.fColorClearValue.color.float32[3] = fClearColor.fRGBA[3];
- cbInfo.fBounds.setEmpty();
+ if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
+ cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
+ } else {
+ cbInfo.fBounds.setEmpty();
+ }
cbInfo.fIsEmpty = true;
cbInfo.fStartsWithClear = false;