1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 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 "experimental/graphite/src/DrawContext.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/private/SkColorData.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "experimental/graphite/src/CommandBuffer.h" 13cb93a386Sopenharmony_ci#include "experimental/graphite/src/DrawList.h" 14cb93a386Sopenharmony_ci#include "experimental/graphite/src/DrawPass.h" 15cb93a386Sopenharmony_ci#include "experimental/graphite/src/RenderPassTask.h" 16cb93a386Sopenharmony_ci#include "experimental/graphite/src/TextureProxy.h" 17cb93a386Sopenharmony_ci#include "experimental/graphite/src/geom/BoundsManager.h" 18cb93a386Sopenharmony_ci#include "experimental/graphite/src/geom/Shape.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_cinamespace skgpu { 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cisk_sp<DrawContext> DrawContext::Make(sk_sp<TextureProxy> target, 23cb93a386Sopenharmony_ci sk_sp<SkColorSpace> colorSpace, 24cb93a386Sopenharmony_ci SkColorType colorType, 25cb93a386Sopenharmony_ci SkAlphaType alphaType) { 26cb93a386Sopenharmony_ci if (!target) { 27cb93a386Sopenharmony_ci return nullptr; 28cb93a386Sopenharmony_ci } 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci // TODO: validate that the color type and alpha type are compatible with the target's info 31cb93a386Sopenharmony_ci SkImageInfo imageInfo = SkImageInfo::Make(target->dimensions(), 32cb93a386Sopenharmony_ci colorType, 33cb93a386Sopenharmony_ci alphaType, 34cb93a386Sopenharmony_ci std::move(colorSpace)); 35cb93a386Sopenharmony_ci return sk_sp<DrawContext>(new DrawContext(std::move(target), imageInfo)); 36cb93a386Sopenharmony_ci} 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciDrawContext::DrawContext(sk_sp<TextureProxy> target, const SkImageInfo& ii) 39cb93a386Sopenharmony_ci : fTarget(std::move(target)) 40cb93a386Sopenharmony_ci , fImageInfo(ii) 41cb93a386Sopenharmony_ci , fPendingDraws(std::make_unique<DrawList>()) { 42cb93a386Sopenharmony_ci // TBD - Will probably want DrawLists (and its internal commands) to come from an arena 43cb93a386Sopenharmony_ci // that the DC manages. 44cb93a386Sopenharmony_ci} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ciDrawContext::~DrawContext() { 47cb93a386Sopenharmony_ci // If the DC is destroyed and there are pending commands, they won't be drawn. 48cb93a386Sopenharmony_ci fPendingDraws.reset(); 49cb93a386Sopenharmony_ci fDrawPasses.clear(); 50cb93a386Sopenharmony_ci} 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_civoid DrawContext::stencilAndFillPath(const Transform& localToDevice, 53cb93a386Sopenharmony_ci const Shape& shape, 54cb93a386Sopenharmony_ci const Clip& clip, 55cb93a386Sopenharmony_ci DrawOrder order, 56cb93a386Sopenharmony_ci const PaintParams* paint) { 57cb93a386Sopenharmony_ci SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 58cb93a386Sopenharmony_ci fPendingDraws->stencilAndFillPath(localToDevice, shape, clip, order,paint); 59cb93a386Sopenharmony_ci} 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_civoid DrawContext::fillConvexPath(const Transform& localToDevice, 62cb93a386Sopenharmony_ci const Shape& shape, 63cb93a386Sopenharmony_ci const Clip& clip, 64cb93a386Sopenharmony_ci DrawOrder order, 65cb93a386Sopenharmony_ci const PaintParams* paint) { 66cb93a386Sopenharmony_ci SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 67cb93a386Sopenharmony_ci fPendingDraws->fillConvexPath(localToDevice, shape, clip, order, paint); 68cb93a386Sopenharmony_ci} 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_civoid DrawContext::strokePath(const Transform& localToDevice, 71cb93a386Sopenharmony_ci const Shape& shape, 72cb93a386Sopenharmony_ci const StrokeParams& stroke, 73cb93a386Sopenharmony_ci const Clip& clip, 74cb93a386Sopenharmony_ci DrawOrder order, 75cb93a386Sopenharmony_ci const PaintParams* paint) { 76cb93a386Sopenharmony_ci SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(clip.scissor())); 77cb93a386Sopenharmony_ci fPendingDraws->strokePath(localToDevice, shape, stroke, clip, order, paint); 78cb93a386Sopenharmony_ci} 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_civoid DrawContext::clear(const SkColor4f& clearColor) { 81cb93a386Sopenharmony_ci fPendingLoadOp = LoadOp::kClear; 82cb93a386Sopenharmony_ci SkPMColor4f pmColor = clearColor.premul(); 83cb93a386Sopenharmony_ci fPendingClearColor = pmColor.array(); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci // a fullscreen clear will overwrite anything that came before, so start a new DrawList 86cb93a386Sopenharmony_ci // and clear any drawpasses that haven't been snapped yet 87cb93a386Sopenharmony_ci fPendingDraws = std::make_unique<DrawList>(); 88cb93a386Sopenharmony_ci fDrawPasses.clear(); 89cb93a386Sopenharmony_ci} 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_civoid DrawContext::snapDrawPass(Recorder* recorder, const BoundsManager* occlusionCuller) { 92cb93a386Sopenharmony_ci if (fPendingDraws->drawCount() == 0) { 93cb93a386Sopenharmony_ci return; 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci auto pass = DrawPass::Make(recorder, std::move(fPendingDraws), fTarget, 97cb93a386Sopenharmony_ci std::make_pair(fPendingLoadOp, fPendingStoreOp), fPendingClearColor, 98cb93a386Sopenharmony_ci occlusionCuller); 99cb93a386Sopenharmony_ci fDrawPasses.push_back(std::move(pass)); 100cb93a386Sopenharmony_ci fPendingDraws = std::make_unique<DrawList>(); 101cb93a386Sopenharmony_ci fPendingLoadOp = LoadOp::kLoad; 102cb93a386Sopenharmony_ci fPendingStoreOp = StoreOp::kStore; 103cb93a386Sopenharmony_ci} 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_cisk_sp<Task> DrawContext::snapRenderPassTask(Recorder* recorder, 106cb93a386Sopenharmony_ci const BoundsManager* occlusionCuller) { 107cb93a386Sopenharmony_ci this->snapDrawPass(recorder, occlusionCuller); 108cb93a386Sopenharmony_ci if (fDrawPasses.empty()) { 109cb93a386Sopenharmony_ci return nullptr; 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci // TODO: At this point we would determine all the targets used by the drawPasses, 113cb93a386Sopenharmony_ci // build up the union of them and store them in the RenderPassDesc. However, for 114cb93a386Sopenharmony_ci // the moment we should have only one drawPass. 115cb93a386Sopenharmony_ci SkASSERT(fDrawPasses.size() == 1); 116cb93a386Sopenharmony_ci RenderPassDesc desc; 117cb93a386Sopenharmony_ci desc.fColorAttachment.fTextureProxy = sk_ref_sp(fDrawPasses[0]->target()); 118cb93a386Sopenharmony_ci std::tie(desc.fColorAttachment.fLoadOp, desc.fColorAttachment.fStoreOp) = fDrawPasses[0]->ops(); 119cb93a386Sopenharmony_ci desc.fClearColor = fDrawPasses[0]->clearColor(); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci return RenderPassTask::Make(std::move(fDrawPasses), desc); 122cb93a386Sopenharmony_ci} 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci} // namespace skgpu 125