Reduce stencil buffer clearing
TBR=bsalomon@google.com Bug: skia:6953 Change-Id: I079f90711297ee290f2d4011cfcb18b764554deb Reviewed-on: https://skia-review.googlesource.com/40691 Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
dff47afd5a
commit
cb2e235e6f
@ -403,6 +403,7 @@ skia_gpu_sources = [
|
||||
"$_src/gpu/gl/GrGLGLSL.h",
|
||||
"$_src/gpu/gl/GrGLGpu.cpp",
|
||||
"$_src/gpu/gl/GrGLGpu.h",
|
||||
"$_src/gpu/gl/GrGLGpuCommandBuffer.cpp",
|
||||
"$_src/gpu/gl/GrGLGpuCommandBuffer.h",
|
||||
"$_src/gpu/gl/GrGLGpuProgramCache.cpp",
|
||||
"$_src/gpu/gl/GrGLExtensions.cpp",
|
||||
|
@ -25,6 +25,8 @@ class GrStencilAttachment;
|
||||
*/
|
||||
class GrRenderTarget : virtual public GrSurface {
|
||||
public:
|
||||
virtual bool alwaysClearStencil() const { return false; }
|
||||
|
||||
// GrSurface overrides
|
||||
GrRenderTarget* asRenderTarget() override { return this; }
|
||||
const GrRenderTarget* asRenderTarget() const override { return this; }
|
||||
|
@ -97,7 +97,7 @@ static std::unique_ptr<GrGpuRTCommandBuffer> create_command_buffer(GrGpu* gpu,
|
||||
GrLoadOp colorLoadOp,
|
||||
GrColor loadClearColor,
|
||||
GrLoadOp stencilLoadOp) {
|
||||
const GrGpuRTCommandBuffer::LoadAndStoreInfo kBasicLoadStoreInfo {
|
||||
const GrGpuRTCommandBuffer::LoadAndStoreInfo kColorLoadStoreInfo {
|
||||
colorLoadOp,
|
||||
GrStoreOp::kStore,
|
||||
loadClearColor
|
||||
@ -115,8 +115,8 @@ static std::unique_ptr<GrGpuRTCommandBuffer> create_command_buffer(GrGpu* gpu,
|
||||
|
||||
std::unique_ptr<GrGpuRTCommandBuffer> buffer(
|
||||
gpu->createCommandBuffer(rt, origin,
|
||||
kBasicLoadStoreInfo, // Color
|
||||
stencilLoadAndStoreInfo)); // Stencil
|
||||
kColorLoadStoreInfo,
|
||||
stencilLoadAndStoreInfo));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -451,6 +451,7 @@ GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget*
|
||||
height = SkNextPow2(height);
|
||||
}
|
||||
#endif
|
||||
SkDEBUGCODE(bool newStencil = false;)
|
||||
GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
|
||||
rt->numStencilSamples(), &sbKey);
|
||||
GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>(
|
||||
@ -460,13 +461,18 @@ GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget*
|
||||
stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height);
|
||||
if (stencil) {
|
||||
this->assignUniqueKeyToResource(sbKey, stencil);
|
||||
SkDEBUGCODE(newStencil = true;)
|
||||
}
|
||||
}
|
||||
if (rt->renderTargetPriv().attachStencilAttachment(stencil)) {
|
||||
#ifdef SK_DEBUG
|
||||
// Fill the SB with an inappropriate value. opLists that use the
|
||||
// SB should clear it properly.
|
||||
this->gpu()->clearStencil(rt, 0xFFFF);
|
||||
if (newStencil) {
|
||||
SkASSERT(stencil->isDirty());
|
||||
this->gpu()->clearStencil(rt, 0xFFFF);
|
||||
SkASSERT(stencil->isDirty());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,7 @@ class GrResourceKey;
|
||||
|
||||
class GrStencilAttachment : public GrGpuResource {
|
||||
public:
|
||||
|
||||
|
||||
virtual ~GrStencilAttachment() {
|
||||
~GrStencilAttachment() override {
|
||||
// TODO: allow SB to be purged and detach itself from rts
|
||||
}
|
||||
|
||||
@ -27,6 +25,9 @@ public:
|
||||
int height() const { return fHeight; }
|
||||
int bits() const { return fBits; }
|
||||
int numSamples() const { return fSampleCnt; }
|
||||
bool isDirty() const { return fIsDirty; }
|
||||
|
||||
void cleared() { fIsDirty = false; }
|
||||
|
||||
// We create a unique stencil buffer at each width, height and sampleCnt and share it for
|
||||
// all render targets that require a stencil with those params.
|
||||
@ -35,11 +36,12 @@ public:
|
||||
|
||||
protected:
|
||||
GrStencilAttachment(GrGpu* gpu, int width, int height, int bits, int sampleCnt)
|
||||
: GrGpuResource(gpu)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fBits(bits)
|
||||
, fSampleCnt(sampleCnt) {
|
||||
: INHERITED(gpu)
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fBits(bits)
|
||||
, fSampleCnt(sampleCnt)
|
||||
, fIsDirty(true) {
|
||||
}
|
||||
|
||||
private:
|
||||
@ -48,6 +50,7 @@ private:
|
||||
int fHeight;
|
||||
int fBits;
|
||||
int fSampleCnt;
|
||||
bool fIsDirty;
|
||||
|
||||
typedef GrGpuResource INHERITED;
|
||||
};
|
||||
|
@ -1960,6 +1960,12 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
|
||||
// this should only be called internally when we know we have a
|
||||
// stencil buffer.
|
||||
SkASSERT(sb);
|
||||
|
||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
||||
this->flushRenderTarget(glRT, &SkIRect::EmptyIRect());
|
||||
|
||||
@ -1970,6 +1976,9 @@ void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
|
||||
GL_CALL(ClearStencil(clearValue));
|
||||
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
|
||||
fHWStencilSettings.invalidate();
|
||||
if (!clearValue) {
|
||||
sb->cleared();
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
|
||||
|
24
src/gpu/gl/GrGLGpuCommandBuffer.cpp
Normal file
24
src/gpu/gl/GrGLGpuCommandBuffer.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrGLGpuCommandBuffer.h"
|
||||
|
||||
#include "GrFixedClip.h"
|
||||
#include "GrRenderTargetPriv.h"
|
||||
|
||||
void GrGLGpuRTCommandBuffer::begin() {
|
||||
if (GrLoadOp::kClear == fColorLoadAndStoreInfo.fLoadOp) {
|
||||
fGpu->clear(GrFixedClip::Disabled(), fColorLoadAndStoreInfo.fClearColor,
|
||||
fRenderTarget, fOrigin);
|
||||
}
|
||||
if (GrLoadOp::kClear == fStencilLoadAndStoreInfo.fLoadOp) {
|
||||
GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
|
||||
if (sb && (sb->isDirty() || fRenderTarget->alwaysClearStencil())) {
|
||||
fGpu->clearStencil(fRenderTarget, 0x0);
|
||||
}
|
||||
}
|
||||
}
|
@ -61,15 +61,7 @@ public:
|
||||
|
||||
~GrGLGpuRTCommandBuffer() override {}
|
||||
|
||||
void begin() override {
|
||||
if (GrLoadOp::kClear == fColorLoadAndStoreInfo.fLoadOp) {
|
||||
fGpu->clear(GrFixedClip::Disabled(), fColorLoadAndStoreInfo.fClearColor,
|
||||
fRenderTarget, fOrigin);
|
||||
}
|
||||
if (GrLoadOp::kClear == fStencilLoadAndStoreInfo.fLoadOp) {
|
||||
fGpu->clearStencil(fRenderTarget, 0x0);
|
||||
}
|
||||
}
|
||||
void begin() override;
|
||||
void end() override {}
|
||||
|
||||
void discard() override { }
|
||||
|
@ -75,7 +75,7 @@ sk_sp<GrGLRenderTarget> GrGLRenderTarget::MakeWrapped(GrGLGpu* gpu,
|
||||
format.fPacked = false;
|
||||
format.fStencilBits = stencilBits;
|
||||
format.fTotalBits = stencilBits;
|
||||
// Owndership of sb is passed to the GrRenderTarget so doesn't need to be deleted
|
||||
// Ownership of sb is passed to the GrRenderTarget so doesn't need to be deleted
|
||||
sb = new GrGLStencilAttachment(gpu, sbDesc, desc.fWidth, desc.fHeight,
|
||||
desc.fSampleCnt, format);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ class GrGLStencilAttachment;
|
||||
|
||||
class GrGLRenderTarget : public GrRenderTarget {
|
||||
public:
|
||||
bool alwaysClearStencil() const override { return 0 == fRTFBOID; }
|
||||
|
||||
// set fTexFBOID to this value to indicate that it is multisampled but
|
||||
// Gr doesn't know how to resolve it.
|
||||
enum { kUnresolvableFBOID = 0 };
|
||||
|
Loading…
Reference in New Issue
Block a user