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