/* * 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 "src/gpu/ops/ClearOp.h" #include "include/gpu/GrRecordingContext.h" #include "src/gpu/GrMemoryPool.h" #include "src/gpu/GrOpFlushState.h" #include "src/gpu/GrOpsRenderPass.h" #include "src/gpu/GrProxyProvider.h" #include "src/gpu/GrRecordingContextPriv.h" namespace { bool contains_scissor(const GrScissorState& a, const GrScissorState& b) { return !a.enabled() || (b.enabled() && a.rect().contains(b.rect())); } } // anonymous namespace namespace skgpu::v1 { GrOp::Owner ClearOp::MakeColor(GrRecordingContext* context, const GrScissorState& scissor, std::array color) { return GrOp::Make(context, Buffer::kColor, scissor, color, false); } GrOp::Owner ClearOp::MakeStencilClip(GrRecordingContext* context, const GrScissorState& scissor, bool insideMask) { return GrOp::Make(context, Buffer::kStencilClip, scissor, std::array(), insideMask); } ClearOp::ClearOp(Buffer buffer, const GrScissorState& scissor, std::array color, bool insideMask) : GrOp(ClassID()) , fScissor(scissor) , fColor(color) , fStencilInsideMask(insideMask) , fBuffer(buffer) { this->setBounds(SkRect::Make(scissor.rect()), HasAABloat::kNo, IsHairline::kNo); } GrOp::CombineResult ClearOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) { auto other = t->cast(); if (other->fBuffer == fBuffer) { // This could be much more complicated. Currently we look at cases where the new clear // contains the old clear, or when the new clear is a subset of the old clear and they clear // to the same value (color or stencil mask depending on target). if (contains_scissor(other->fScissor, fScissor)) { fScissor = other->fScissor; fColor = other->fColor; fStencilInsideMask = other->fStencilInsideMask; return CombineResult::kMerged; } else if (other->fColor == fColor && other->fStencilInsideMask == fStencilInsideMask && contains_scissor(fScissor, other->fScissor)) { return CombineResult::kMerged; } } else if (other->fScissor == fScissor) { // When the scissors are the exact same but the buffers are different, we can combine and // clear both stencil and clear together in onExecute(). if (other->fBuffer & Buffer::kColor) { fColor = other->fColor; } if (other->fBuffer & Buffer::kStencilClip) { fStencilInsideMask = other->fStencilInsideMask; } fBuffer = Buffer::kBoth; return CombineResult::kMerged; } return CombineResult::kCannotCombine; } void ClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) { SkASSERT(state->opsRenderPass()); if (fBuffer & Buffer::kColor) { state->opsRenderPass()->clear(fScissor, fColor); } if (fBuffer & Buffer::kStencilClip) { state->opsRenderPass()->clearStencilClip(fScissor, fStencilInsideMask); } } } // namespace skgpu::v1