Only use scissor state for native clears

This is the first of many CLs that progressively refine the clipping,
scissoring, and clearing APIs.

The series of changes focus on simplifying the clear APIs, consolidating
clip intersection logic, and moving towards a more explicitly sized
render target context (where confusion between approx-fit and exact-fit
is handled externally, although I don't take it that far).

Next step will be to propagate the simpler calls up to GrRTC.

Bug:skia:10205
Change-Id: Idb0c58a63b7a3950a92604dd4c03536d668be7c4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/290123
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Michael Ludwig 2020-05-21 12:45:31 -04:00 committed by Skia Commit-Bot
parent 1f60733fb3
commit 1e63279156
24 changed files with 135 additions and 155 deletions

View File

@ -11,12 +11,13 @@
#include "include/gpu/GrContext.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrFixedClip.h"
#include "src/gpu/GrCpuBuffer.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrPrimitiveProcessor.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrRenderTargetPriv.h"
#include "src/gpu/GrScissorState.h"
#include "src/gpu/GrSimpleMesh.h"
#include "src/gpu/GrTexturePriv.h"
@ -37,21 +38,22 @@ void GrOpsRenderPass::end() {
this->resetActiveBuffers();
}
void GrOpsRenderPass::clear(const GrFixedClip& clip, const SkPMColor4f& color) {
void GrOpsRenderPass::clear(const GrScissorState& scissor, const SkPMColor4f& color) {
SkASSERT(fRenderTarget);
// A clear at this level will always be a true clear, so make sure clears were not supposed to
// be redirected to draws instead
SkASSERT(!this->gpu()->caps()->performColorClearsAsDraws());
SkASSERT(!clip.scissorEnabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
this->onClear(clip, color);
this->onClear(scissor, color);
}
void GrOpsRenderPass::clearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
void GrOpsRenderPass::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
// As above, make sure the stencil clear wasn't supposed to be a draw rect with stencil settings
SkASSERT(!this->gpu()->caps()->performStencilClearsAsDraws());
SkASSERT(!scissor.enabled() || !this->gpu()->caps()->performPartialClearsAsDraws());
fDrawPipelineStatus = DrawPipelineStatus::kNotConfigured;
this->onClearStencilClip(clip, insideStencilMask);
this->onClearStencilClip(scissor, insideStencilMask);
}
void GrOpsRenderPass::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable) {

View File

@ -13,12 +13,12 @@
#include "src/gpu/ops/GrDrawOp.h"
class GrOpFlushState;
class GrFixedClip;
class GrGpu;
class GrPipeline;
class GrPrimitiveProcessor;
class GrProgramInfo;
class GrRenderTarget;
class GrScissorState;
class GrSemaphore;
struct SkIRect;
struct SkRect;
@ -120,11 +120,17 @@ public:
virtual void inlineUpload(GrOpFlushState*, GrDeferredTextureUploadFn&) = 0;
/**
* Clear the owned render target. Ignores the draw state and clip.
* Clear the owned render target. Clears the full target if 'scissor' is disabled, otherwise it
* is restricted to 'scissor'. Must check caps.performPartialClearsAsDraws() before using an
* enabled scissor test; must check caps.performColorClearsAsDraws() before using this at all.
*/
void clear(const GrFixedClip&, const SkPMColor4f&);
void clear(const GrScissorState& scissor, const SkPMColor4f&);
void clearStencilClip(const GrFixedClip&, bool insideStencilMask);
/**
* Same as clear() but modifies the stencil; check caps.performStencilClearsAsDraws() and
* caps.performPartialClearsAsDraws().
*/
void clearStencilClip(const GrScissorState& scissor, bool insideStencilMask);
/**
* Executes the SkDrawable object for the underlying backend.
@ -189,8 +195,8 @@ private:
virtual void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) {
SK_ABORT("Not implemented."); // Only called if caps.nativeDrawIndirectSupport().
}
virtual void onClear(const GrFixedClip&, const SkPMColor4f&) = 0;
virtual void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) = 0;
virtual void onClear(const GrScissorState&, const SkPMColor4f&) = 0;
virtual void onClearStencilClip(const GrScissorState&, bool insideStencilMask) = 0;
virtual void onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler>) {}
enum class DrawPipelineStatus {

View File

@ -558,7 +558,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
fContext, SkIRect::MakeEmpty(), color, /* fullscreen */ true));
}
} else {
if (this->caps()->performPartialClearsAsDraws()) {
if (this->caps()->performPartialClearsAsDraws() || clip.hasWindowRectangles()) {
// performPartialClearsAsDraws() also returns true if any clear has to be a draw.
GrPaint paint;
clear_to_grpaint(color, &paint);
@ -567,7 +567,7 @@ void GrRenderTargetContext::internalClear(const GrFixedClip& clip,
GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
SkRect::Make(clip.scissorRect())));
} else {
std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, clip, color,
std::unique_ptr<GrOp> op(GrClearOp::Make(fContext, clip.scissorState(), color,
this->asSurfaceProxy()));
// This version of the clear op factory can return null if the clip doesn't intersect
// with the surface proxy's boundary
@ -979,18 +979,23 @@ void GrRenderTargetContextPriv::clearStencilClip(const GrFixedClip& clip, bool i
void GrRenderTargetContext::internalStencilClear(const GrFixedClip& clip, bool insideStencilMask) {
this->setNeedsStencil(/* useMixedSamplesIfNotMSAA = */ false);
if (this->caps()->performStencilClearsAsDraws()) {
bool clearWithDraw = this->caps()->performStencilClearsAsDraws() ||
(clip.scissorEnabled() && this->caps()->performPartialClearsAsDraws());
// TODO(michaelludwig): internalStencilClear will eventually just take a GrScissorState so
// we won't need to check window rectangles here.
if (clearWithDraw || clip.hasWindowRectangles()) {
const GrUserStencilSettings* ss = GrStencilSettings::SetClipBitSettings(insideStencilMask);
SkRect rtRect = SkRect::MakeWH(this->width(), this->height());
SkRect rect = clip.scissorEnabled() ? SkRect::Make(clip.scissorRect())
: SkRect::MakeWH(this->width(), this->height());
// Configure the paint to have no impact on the color buffer
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
this->addDrawOp(clip, GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
rtRect, ss));
rect, ss));
} else {
std::unique_ptr<GrOp> op(GrClearStencilClipOp::Make(fContext, clip, insideStencilMask,
this->asRenderTargetProxy()));
std::unique_ptr<GrOp> op(GrClearStencilClipOp::Make(
fContext, clip.scissorState(), insideStencilMask, this->asRenderTargetProxy()));
if (!op) {
return;
}

View File

@ -7,6 +7,7 @@
#include "src/gpu/d3d/GrD3DCommandList.h"
#include "src/gpu/GrScissorState.h"
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipelineState.h"
@ -296,12 +297,13 @@ void GrD3DDirectCommandList::drawIndexedInstanced(unsigned int indexCount,
void GrD3DDirectCommandList::clearRenderTargetView(GrD3DRenderTarget* renderTarget,
const SkPMColor4f& color,
const GrFixedClip& clip) {
const GrScissorState& scissor) {
SkASSERT(!scissor.enabled()); // no cliprects for now
this->addingWork();
this->addResource(renderTarget->resource());
fCommandList->ClearRenderTargetView(renderTarget->colorRenderTargetView(),
color.vec(),
0, NULL); // no cliprects for now
0, NULL);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -22,7 +22,7 @@ class GrD3DRenderTarget;
class GrD3DRootSignature;
class GrD3DTextureResource;
class GrFixedClip;
class GrScissorState;
class GrD3DCommandList {
public:
@ -134,7 +134,7 @@ public:
unsigned int startInstance);
void clearRenderTargetView(GrD3DRenderTarget* renderTarget, const SkPMColor4f& color,
const GrFixedClip& clip);
const GrScissorState& scissor);
private:
GrD3DDirectCommandList(gr_cp<ID3D12CommandAllocator> allocator,
gr_cp<ID3D12GraphicsCommandList> commandList);

View File

@ -563,12 +563,12 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width,
return true;
}
void GrD3DGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color, GrRenderTarget* rt) {
void GrD3DGpu::clear(const GrScissorState& scissor, const SkPMColor4f& color, GrRenderTarget* rt) {
GrD3DRenderTarget* d3dRT = static_cast<GrD3DRenderTarget*>(rt);
d3dRT->setResourceState(this, D3D12_RESOURCE_STATE_RENDER_TARGET);
fCurrentDirectCommandList->clearRenderTargetView(d3dRT, color, clip);
fCurrentDirectCommandList->clearRenderTargetView(d3dRT, color, scissor);
}
static bool check_resource_info(const GrD3DTextureResourceInfo& info) {

View File

@ -99,7 +99,7 @@ public:
return nullptr;
}
void clear(const GrFixedClip& clip, const SkPMColor4f& color, GrRenderTarget*);
void clear(const GrScissorState& scissor, const SkPMColor4f& color, GrRenderTarget*);
void submit(GrOpsRenderPass* renderPass) override;

View File

@ -46,8 +46,7 @@ GrGpu* GrD3DOpsRenderPass::gpu() { return fGpu; }
void GrD3DOpsRenderPass::onBegin() {
if (GrLoadOp::kClear == fColorLoadOp) {
GrFixedClip clip;
fGpu->clear(clip, fClearColor, fRenderTarget);
fGpu->clear(GrScissorState(), fClearColor, fRenderTarget);
}
}
@ -234,6 +233,6 @@ void GrD3DOpsRenderPass::onDrawIndexedInstanced(int indexCount, int baseIndex, i
fGpu->stats()->incNumDraws();
}
void GrD3DOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
fGpu->clear(clip, color, fRenderTarget);
void GrD3DOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) {
fGpu->clear(scissor, color, fRenderTarget);
}

View File

@ -56,9 +56,9 @@ private:
void onDrawIndirect(const GrBuffer*, size_t offset, int drawCount) override {}
void onDrawIndexedIndirect(const GrBuffer*, size_t offset, int drawCount) override {}
void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override {}
GrD3DGpu* fGpu;

View File

@ -94,12 +94,15 @@ void GrDawnOpsRenderPass::submit() {
fGpu->appendCommandBuffer(fEncoder.Finish());
}
void GrDawnOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
void GrDawnOpsRenderPass::onClearStencilClip(const GrScissorState& scissor,
bool insideStencilMask) {
SkASSERT(!scissor.enabled());
fPassEncoder.EndPass();
fPassEncoder = beginRenderPass(wgpu::LoadOp::Load, wgpu::LoadOp::Clear);
}
void GrDawnOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
void GrDawnOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) {
SkASSERT(!scissor.enabled());
fPassEncoder.EndPass();
fPassEncoder = beginRenderPass(wgpu::LoadOp::Clear, wgpu::LoadOp::Load);
}

View File

@ -51,9 +51,9 @@ private:
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
int baseVertex) override;
void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override;
struct InlineUploadInfo {
InlineUploadInfo(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload)

View File

@ -1869,51 +1869,29 @@ GrGLenum GrGLGpu::bindBuffer(GrGpuBufferType type, const GrBuffer* buffer) {
return bufferState->fGLTarget;
}
void GrGLGpu::clear(const GrFixedClip& clip, const SkPMColor4f& color,
void GrGLGpu::clear(const GrScissorState& scissor, const SkPMColor4f& color,
GrRenderTarget* target, GrSurfaceOrigin origin) {
// parent class should never let us get here with no RT
SkASSERT(target);
SkASSERT(!this->caps()->performColorClearsAsDraws());
SkASSERT(!clip.scissorEnabled() || !this->caps()->performPartialClearsAsDraws());
SkASSERT(!scissor.enabled() || !this->caps()->performPartialClearsAsDraws());
this->handleDirtyContext();
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
if (clip.scissorEnabled()) {
this->flushRenderTarget(glRT, origin, clip.scissorRect());
if (scissor.enabled()) {
this->flushRenderTarget(glRT, origin, scissor.rect());
} else {
this->flushRenderTarget(glRT);
}
this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
this->flushScissor(scissor, glRT->width(), glRT->height(), origin);
this->disableWindowRectangles();
this->flushColorWrite(true);
this->flushClearColor(color);
GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
}
void GrGLGpu::clearStencil(GrRenderTarget* target, int clearValue) {
SkASSERT(!this->caps()->performStencilClearsAsDraws());
if (!target) {
return;
}
// This should only be called internally when we know we have a stencil buffer.
SkASSERT(target->renderTargetPriv().getStencilAttachment());
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTargetNoColorWrites(glRT);
this->flushScissorTest(GrScissorTest::kDisabled);
this->disableWindowRectangles();
GL_CALL(StencilMask(0xffffffff));
GL_CALL(ClearStencil(clearValue));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
fHWStencilSettings.invalidate();
}
static bool use_tiled_rendering(const GrGLCaps& glCaps,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore) {
// Only use the tiled rendering extension if we can explicitly clear and discard the stencil.
@ -2011,11 +1989,11 @@ void GrGLGpu::endCommandBuffer(GrRenderTarget* rt,
SkDEBUGCODE(fIsExecutingCommandBuffer_DebugOnly = false);
}
void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
bool insideStencilMask,
void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencilMask,
GrRenderTarget* target, GrSurfaceOrigin origin) {
SkASSERT(target);
SkASSERT(!this->caps()->performStencilClearsAsDraws());
SkASSERT(!scissor.enabled() || !this->caps()->performPartialClearsAsDraws());
this->handleDirtyContext();
GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
@ -2046,8 +2024,8 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
this->flushRenderTargetNoColorWrites(glRT);
this->flushScissor(clip.scissorState(), glRT->width(), glRT->height(), origin);
this->flushWindowRectangles(clip.windowRectsState(), glRT, origin);
this->flushScissor(scissor, glRT->width(), glRT->height(), origin);
this->disableWindowRectangles();
GL_CALL(StencilMask((uint32_t) clipStencilMask));
GL_CALL(ClearStencil(value));
@ -2281,11 +2259,10 @@ void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resol
fHWBoundRenderTargetUniqueID.makeInvalid();
if (GrGLCaps::kES_Apple_MSFBOType == this->glCaps().msFBOType()) {
// Apple's extension uses the scissor as the blit bounds.
GrScissorState scissorState;
scissorState.set(resolveRect);
// Passing in kTopLeft_GrSurfaceOrigin will make sure no transformation of the rect
// happens inside flushScissor since resolveRect is already in native device coordinates.
this->flushScissor(scissorState, rt->width(), rt->height(), kTopLeft_GrSurfaceOrigin);
this->flushScissor(GrScissorState(resolveRect), rt->width(), rt->height(),
kTopLeft_GrSurfaceOrigin);
this->disableWindowRectangles();
GL_CALL(ResolveMultisampleFramebuffer());
} else {

View File

@ -104,18 +104,14 @@ public:
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
// Thus this is the implementation of the clear call for the corresponding passthrough function
// on GrGLOpsRenderPass.
void clear(const GrFixedClip&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
void clear(const GrScissorState&, const SkPMColor4f&, GrRenderTarget*, GrSurfaceOrigin);
// The GrGLOpsRenderPass does not buffer up draws before submitting them to the gpu.
// Thus this is the implementation of the clearStencil call for the corresponding passthrough
// function on GrGLOpsrenderPass.
void clearStencilClip(const GrFixedClip&, bool insideStencilMask,
void clearStencilClip(const GrScissorState&, bool insideStencilMask,
GrRenderTarget*, GrSurfaceOrigin);
// FIXME (michaelludwig): Can this go away and just use clearStencilClip() + marking the
// stencil buffer as not dirty?
void clearStencil(GrRenderTarget*, int clearValue);
void beginCommandBuffer(GrRenderTarget*, const SkIRect& bounds, GrSurfaceOrigin,
const GrOpsRenderPass::LoadAndStoreInfo& colorLoadStore,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilLoadStore);

View File

@ -259,12 +259,10 @@ void GrGLOpsRenderPass::onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer
}
}
void GrGLOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
fGpu->clear(clip, color, fRenderTarget, fOrigin);
void GrGLOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) {
fGpu->clear(scissor, color, fRenderTarget, fOrigin);
}
void GrGLOpsRenderPass::onClearStencilClip(const GrFixedClip& clip,
bool insideStencilMask) {
fGpu->clearStencilClip(clip, insideStencilMask, fRenderTarget, fOrigin);
void GrGLOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
fGpu->clearStencilClip(scissor, insideStencilMask, fRenderTarget, fOrigin);
}

View File

@ -69,8 +69,8 @@ private:
void onDrawIndirect(const GrBuffer* drawIndirectBuffer, size_t offset, int drawCount) override;
void onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t offset,
int drawCount) override;
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override;
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override;
GrGLGpu* fGpu;
SkIRect fContentBounds;
@ -89,4 +89,3 @@ private:
};
#endif

View File

@ -45,8 +45,10 @@ private:
void onDrawIndexedInstanced(int, int, int, int, int) override { this->dummyDraw(); }
void onDrawIndirect(const GrBuffer*, size_t, int) override { this->dummyDraw(); }
void onDrawIndexedIndirect(const GrBuffer*, size_t, int) override { this->dummyDraw(); }
void onClear(const GrFixedClip&, const SkPMColor4f&) override { this->markRenderTargetDirty(); }
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override {}
void onClear(const GrScissorState& scissor, const SkPMColor4f&) override {
this->markRenderTargetDirty();
}
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override {}
void dummyDraw() {
this->markRenderTargetDirty();
++fNumDraws;

View File

@ -49,9 +49,9 @@ private:
void onDrawIndexedInstanced(int indexCount, int baseIndex, int instanceCount, int baseInstance,
int baseVertex) override;
void onClear(const GrFixedClip& clip, const SkPMColor4f& color) override;
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
void onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) override;
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override;
void setupRenderPass(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo);
@ -80,4 +80,3 @@ private:
};
#endif

View File

@ -123,7 +123,10 @@ bool GrMtlOpsRenderPass::onBindTextures(const GrPrimitiveProcessor& primProc,
return true;
}
void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
void GrMtlOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) {
// Partial clears are not supported
SkASSERT(!scissor.enabled());
// Ideally we should never end up here since all clears should either be done as draws or
// load ops in metal. However, if a client inserts a wait op we need to handle it.
fRenderPassDesc.colorAttachments[0].clearColor =
@ -135,8 +138,9 @@ void GrMtlOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& col
fGpu->commandBuffer()->getRenderCommandEncoder(fRenderPassDesc, nullptr, this);
}
void GrMtlOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
SkASSERT(!clip.hasWindowRectangles());
void GrMtlOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
// Partial clears are not supported
SkASSERT(!scissor.enabled());
GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
// this should only be called internally when we know we have a

View File

@ -15,17 +15,17 @@
#include "src/gpu/GrRecordingContextPriv.h"
std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
const GrFixedClip& clip,
const GrScissorState& scissor,
const SkPMColor4f& color,
GrSurfaceProxy* dstProxy) {
const SkIRect rect = SkIRect::MakeSize(dstProxy->dimensions());
if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rect)) {
if (scissor.enabled() && !SkIRect::Intersects(scissor.rect(), rect)) {
return nullptr;
}
GrOpMemoryPool* pool = context->priv().opMemoryPool();
return pool->allocate<GrClearOp>(clip, color, dstProxy);
return pool->allocate<GrClearOp>(scissor, color, dstProxy);
}
std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
@ -39,27 +39,27 @@ std::unique_ptr<GrClearOp> GrClearOp::Make(GrRecordingContext* context,
return pool->allocate<GrClearOp>(rect, color, fullScreen);
}
GrClearOp::GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy)
GrClearOp::GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy)
: INHERITED(ClassID())
, fClip(clip)
, fScissor(scissor)
, fColor(color) {
const SkIRect rtRect = SkIRect::MakeSize(proxy->dimensions());
if (fClip.scissorEnabled()) {
if (fScissor.enabled()) {
// Don't let scissors extend outside the RT. This may improve op combining.
if (!fClip.intersect(rtRect)) {
if (!fScissor.intersect(rtRect)) {
SkASSERT(0); // should be caught upstream
fClip = GrFixedClip(SkIRect::MakeEmpty());
fScissor.set(SkIRect::MakeEmpty());
}
if (proxy->isFunctionallyExact() && fClip.scissorRect() == rtRect) {
fClip.disableScissor();
if (proxy->isFunctionallyExact() && fScissor.rect() == rtRect) {
fScissor.setDisabled();
}
}
this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect),
this->setBounds(SkRect::Make(fScissor.enabled() ? fScissor.rect() : rtRect),
HasAABloat::kNo, IsHairline::kNo);
}
void GrClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
SkASSERT(state->opsRenderPass());
state->opsRenderPass()->clear(fClip, fColor);
state->opsRenderPass()->clear(fScissor, fColor);
}

View File

@ -8,7 +8,7 @@
#ifndef GrClearOp_DEFINED
#define GrClearOp_DEFINED
#include "src/gpu/GrFixedClip.h"
#include "src/gpu/GrScissorState.h"
#include "src/gpu/ops/GrOp.h"
class GrOpFlushState;
@ -19,7 +19,7 @@ public:
DEFINE_OP_CLASS_ID
static std::unique_ptr<GrClearOp> Make(GrRecordingContext* context,
const GrFixedClip& clip,
const GrScissorState& scissor,
const SkPMColor4f& color,
GrSurfaceProxy* dstProxy);
@ -35,8 +35,8 @@ public:
SkString string;
string.append(INHERITED::dumpInfo());
string.appendf("Scissor [ ");
if (fClip.scissorEnabled()) {
const SkIRect& r = fClip.scissorRect();
if (fScissor.enabled()) {
const SkIRect& r = fScissor.rect();
string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
} else {
string.append("disabled");
@ -52,15 +52,15 @@ public:
private:
friend class GrOpMemoryPool; // for ctors
GrClearOp(const GrFixedClip& clip, const SkPMColor4f& color, GrSurfaceProxy* proxy);
GrClearOp(const GrScissorState& scissor, const SkPMColor4f& color, GrSurfaceProxy* proxy);
GrClearOp(const SkIRect& rect, const SkPMColor4f& color, bool fullScreen)
: INHERITED(ClassID())
, fClip(GrFixedClip(rect))
, fScissor(rect)
, fColor(color) {
if (fullScreen) {
fClip.disableScissor();
fScissor.setDisabled();
}
this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsHairline::kNo);
}
@ -71,11 +71,8 @@ private:
// contains the old clear, or when the new clear is a subset of the old clear and is the
// same color.
GrClearOp* cb = t->cast<GrClearOp>();
if (fClip.windowRectsState() != cb->fClip.windowRectsState()) {
return CombineResult::kCannotCombine;
}
if (cb->contains(this)) {
fClip = cb->fClip;
fScissor = cb->fScissor;
fColor = cb->fColor;
return CombineResult::kMerged;
} else if (cb->fColor == fColor && this->contains(cb)) {
@ -86,9 +83,8 @@ private:
bool contains(const GrClearOp* that) const {
// The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
return !fClip.scissorEnabled() ||
(that->fClip.scissorEnabled() &&
fClip.scissorRect().contains(that->fClip.scissorRect()));
return !fScissor.enabled() ||
(that->fScissor.enabled() && fScissor.rect().contains(that->fScissor.rect()));
}
void onPrePrepare(GrRecordingContext*,
@ -100,8 +96,8 @@ private:
void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override;
GrFixedClip fClip;
SkPMColor4f fColor;
GrScissorState fScissor;
SkPMColor4f fColor;
typedef GrOp INHERITED;
};

View File

@ -14,15 +14,15 @@
#include "src/gpu/GrRecordingContextPriv.h"
std::unique_ptr<GrOp> GrClearStencilClipOp::Make(GrRecordingContext* context,
const GrFixedClip& clip,
const GrScissorState& scissor,
bool insideStencilMask,
GrRenderTargetProxy* proxy) {
GrOpMemoryPool* pool = context->priv().opMemoryPool();
return pool->allocate<GrClearStencilClipOp>(clip, insideStencilMask, proxy);
return pool->allocate<GrClearStencilClipOp>(scissor, insideStencilMask, proxy);
}
void GrClearStencilClipOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
SkASSERT(state->opsRenderPass());
state->opsRenderPass()->clearStencilClip(fClip, fInsideStencilMask);
state->opsRenderPass()->clearStencilClip(fScissor, fInsideStencilMask);
}

View File

@ -8,8 +8,8 @@
#ifndef GrClearStencilClipOp_DEFINED
#define GrClearStencilClipOp_DEFINED
#include "src/gpu/GrFixedClip.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrScissorState.h"
#include "src/gpu/ops/GrOp.h"
class GrOpFlushState;
@ -20,7 +20,7 @@ public:
DEFINE_OP_CLASS_ID
static std::unique_ptr<GrOp> Make(GrRecordingContext* context,
const GrFixedClip& clip,
const GrScissorState& scissor,
bool insideStencilMask,
GrRenderTargetProxy* proxy);
@ -29,8 +29,8 @@ public:
#ifdef SK_DEBUG
SkString dumpInfo() const override {
SkString string("Scissor [");
if (fClip.scissorEnabled()) {
const SkIRect& r = fClip.scissorRect();
if (fScissor.enabled()) {
const SkIRect& r = fScissor.rect();
string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
} else {
string.append("disabled");
@ -44,13 +44,13 @@ public:
private:
friend class GrOpMemoryPool; // for ctor
GrClearStencilClipOp(const GrFixedClip& clip, bool insideStencilMask,
GrClearStencilClipOp(const GrScissorState& scissor, bool insideStencilMask,
GrRenderTargetProxy* proxy)
: INHERITED(ClassID())
, fClip(clip)
, fScissor(scissor)
, fInsideStencilMask(insideStencilMask) {
const SkRect& bounds =
fClip.scissorEnabled() ? SkRect::Make(fClip.scissorRect()) : proxy->getBoundsRect();
fScissor.enabled() ? SkRect::Make(fScissor.rect()) : proxy->getBoundsRect();
this->setBounds(bounds, HasAABloat::kNo, IsHairline::kNo);
}
@ -63,8 +63,8 @@ private:
void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
const GrFixedClip fClip;
const bool fInsideStencilMask;
const GrScissorState fScissor;
const bool fInsideStencilMask;
typedef GrOp INHERITED;
};

View File

@ -265,14 +265,12 @@ bool GrVkOpsRenderPass::wrapsSecondaryCommandBuffer() const {
////////////////////////////////////////////////////////////////////////////////
void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
void GrVkOpsRenderPass::onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) {
if (!fCurrentRenderPass) {
SkASSERT(fGpu->isDeviceLost());
return;
}
SkASSERT(!clip.hasWindowRectangles());
GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
// this should only be called internally when we know we have a
// stencil buffer.
@ -293,14 +291,13 @@ void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideS
VkClearRect clearRect;
// Flip rect if necessary
SkIRect vkRect;
if (!clip.scissorEnabled()) {
if (!scissor.enabled()) {
vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
} else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
vkRect = clip.scissorRect();
vkRect = scissor.rect();
} else {
const SkIRect& scissor = clip.scissorRect();
vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
scissor.fRight, fRenderTarget->height() - scissor.fTop);
vkRect.setLTRB(scissor.rect().fLeft, fRenderTarget->height() - scissor.rect().fBottom,
scissor.rect().fRight, fRenderTarget->height() - scissor.rect().fTop);
}
clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
@ -321,15 +318,12 @@ void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideS
fCurrentCBIsEmpty = false;
}
void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
void GrVkOpsRenderPass::onClear(const GrScissorState& scissor, const SkPMColor4f& color) {
if (!fCurrentRenderPass) {
SkASSERT(fGpu->isDeviceLost());
return;
}
// parent class should never let us get here with no RT
SkASSERT(!clip.hasWindowRectangles());
VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}};
// If we end up in a situation where we are calling clear without a scissior then in general it
@ -338,20 +332,19 @@ void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& colo
// load op (e.g. if we needed to execute a wait op). Thus we also have the empty check here.
// TODO: Make the waitOp a RenderTask instead so we can clear out the GrOpsTask for a clear. We
// can then reenable this assert assuming we can't get messed up by a waitOp.
//SkASSERT(!fCurrentCBIsEmpty || clip.scissorEnabled());
//SkASSERT(!fCurrentCBIsEmpty || scissor);
// We always do a sub rect clear with clearAttachments since we are inside a render pass
VkClearRect clearRect;
// Flip rect if necessary
SkIRect vkRect;
if (!clip.scissorEnabled()) {
if (!scissor.enabled()) {
vkRect.setXYWH(0, 0, fRenderTarget->width(), fRenderTarget->height());
} else if (kBottomLeft_GrSurfaceOrigin != fOrigin) {
vkRect = clip.scissorRect();
vkRect = scissor.rect();
} else {
const SkIRect& scissor = clip.scissorRect();
vkRect.setLTRB(scissor.fLeft, fRenderTarget->height() - scissor.fBottom,
scissor.fRight, fRenderTarget->height() - scissor.fTop);
vkRect.setLTRB(scissor.rect().fLeft, fRenderTarget->height() - scissor.rect().fBottom,
scissor.rect().fRight, fRenderTarget->height() - scissor.rect().fTop);
}
clearRect.rect.offset = { vkRect.fLeft, vkRect.fTop };
clearRect.rect.extent = { (uint32_t)vkRect.width(), (uint32_t)vkRect.height() };
@ -682,4 +675,3 @@ void GrVkOpsRenderPass::onExecuteDrawable(std::unique_ptr<SkDrawable::GpuDrawHan
drawable->draw(info);
fGpu->addDrawable(std::move(drawable));
}

View File

@ -84,9 +84,9 @@ private:
void onDrawIndexedIndirect(const GrBuffer* drawIndirectBuffer, size_t offset,
int drawCount) override;
void onClear(const GrFixedClip&, const SkPMColor4f& color) override;
void onClear(const GrScissorState& scissor, const SkPMColor4f& color) override;
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
void onClearStencilClip(const GrScissorState& scissor, bool insideStencilMask) override;
void addAdditionalRenderPass(bool mustUseSecondaryCommandBuffer);