1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/ops/ClearOp.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/GrRecordingContext.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrOpsRenderPass.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cinamespace { 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_cibool contains_scissor(const GrScissorState& a, const GrScissorState& b) { 20cb93a386Sopenharmony_ci return !a.enabled() || (b.enabled() && a.rect().contains(b.rect())); 21cb93a386Sopenharmony_ci} 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci} // anonymous namespace 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_cinamespace skgpu::v1 { 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ciGrOp::Owner ClearOp::MakeColor(GrRecordingContext* context, 28cb93a386Sopenharmony_ci const GrScissorState& scissor, 29cb93a386Sopenharmony_ci std::array<float, 4> color) { 30cb93a386Sopenharmony_ci return GrOp::Make<ClearOp>(context, Buffer::kColor, scissor, color, false); 31cb93a386Sopenharmony_ci} 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ciGrOp::Owner ClearOp::MakeStencilClip(GrRecordingContext* context, 34cb93a386Sopenharmony_ci const GrScissorState& scissor, 35cb93a386Sopenharmony_ci bool insideMask) { 36cb93a386Sopenharmony_ci return GrOp::Make<ClearOp>(context, 37cb93a386Sopenharmony_ci Buffer::kStencilClip, 38cb93a386Sopenharmony_ci scissor, 39cb93a386Sopenharmony_ci std::array<float, 4>(), 40cb93a386Sopenharmony_ci insideMask); 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ciClearOp::ClearOp(Buffer buffer, 44cb93a386Sopenharmony_ci const GrScissorState& scissor, 45cb93a386Sopenharmony_ci std::array<float, 4> color, 46cb93a386Sopenharmony_ci bool insideMask) 47cb93a386Sopenharmony_ci : GrOp(ClassID()) 48cb93a386Sopenharmony_ci , fScissor(scissor) 49cb93a386Sopenharmony_ci , fColor(color) 50cb93a386Sopenharmony_ci , fStencilInsideMask(insideMask) 51cb93a386Sopenharmony_ci , fBuffer(buffer) { 52cb93a386Sopenharmony_ci this->setBounds(SkRect::Make(scissor.rect()), HasAABloat::kNo, IsHairline::kNo); 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ciGrOp::CombineResult ClearOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) { 56cb93a386Sopenharmony_ci auto other = t->cast<ClearOp>(); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci if (other->fBuffer == fBuffer) { 59cb93a386Sopenharmony_ci // This could be much more complicated. Currently we look at cases where the new clear 60cb93a386Sopenharmony_ci // contains the old clear, or when the new clear is a subset of the old clear and they clear 61cb93a386Sopenharmony_ci // to the same value (color or stencil mask depending on target). 62cb93a386Sopenharmony_ci if (contains_scissor(other->fScissor, fScissor)) { 63cb93a386Sopenharmony_ci fScissor = other->fScissor; 64cb93a386Sopenharmony_ci fColor = other->fColor; 65cb93a386Sopenharmony_ci fStencilInsideMask = other->fStencilInsideMask; 66cb93a386Sopenharmony_ci return CombineResult::kMerged; 67cb93a386Sopenharmony_ci } else if (other->fColor == fColor && other->fStencilInsideMask == fStencilInsideMask && 68cb93a386Sopenharmony_ci contains_scissor(fScissor, other->fScissor)) { 69cb93a386Sopenharmony_ci return CombineResult::kMerged; 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci } else if (other->fScissor == fScissor) { 72cb93a386Sopenharmony_ci // When the scissors are the exact same but the buffers are different, we can combine and 73cb93a386Sopenharmony_ci // clear both stencil and clear together in onExecute(). 74cb93a386Sopenharmony_ci if (other->fBuffer & Buffer::kColor) { 75cb93a386Sopenharmony_ci fColor = other->fColor; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci if (other->fBuffer & Buffer::kStencilClip) { 78cb93a386Sopenharmony_ci fStencilInsideMask = other->fStencilInsideMask; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci fBuffer = Buffer::kBoth; 81cb93a386Sopenharmony_ci return CombineResult::kMerged; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 84cb93a386Sopenharmony_ci} 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_civoid ClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) { 87cb93a386Sopenharmony_ci SkASSERT(state->opsRenderPass()); 88cb93a386Sopenharmony_ci if (fBuffer & Buffer::kColor) { 89cb93a386Sopenharmony_ci state->opsRenderPass()->clear(fScissor, fColor); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci if (fBuffer & Buffer::kStencilClip) { 93cb93a386Sopenharmony_ci state->opsRenderPass()->clearStencilClip(fScissor, fStencilInsideMask); 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci} // namespace skgpu::v1 98cb93a386Sopenharmony_ci 99